aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--apps/CMakeLists.txt11
-rw-r--r--apps/higet/higet.cc27
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/api.h3
-rw-r--r--ctrl/libhicnctrl/src/hicn_plugin_api.c629
-rw-r--r--ctrl/sysrepo-plugins/hicn-plugin/plugin/hicn_plugin.c6
-rw-r--r--ctrl/sysrepo-plugins/hicn-plugin/plugin/ietf/ietf_interface.c13
-rw-r--r--ctrl/sysrepo-plugins/hicn-plugin/plugin/mainpage.dox48
-rw-r--r--ctrl/sysrepo-plugins/hicn-plugin/plugin/model/hicn_model.c1739
-rw-r--r--ctrl/sysrepo-plugins/yang/hicn/hicn.yang509
-rw-r--r--docs/doxygen/CMakeLists.txt (renamed from lib/doc/CMakeLists.txt)2
-rw-r--r--docs/doxygen/Doxyfile.in (renamed from lib/doc/Doxyfile.in)4
-rw-r--r--docs/source/control.md59
-rw-r--r--docs/source/vpp-plugin.md88
-rw-r--r--hicn-plugin/src/CMakeLists.txt45
-rw-r--r--hicn-plugin/src/cache_policies/cs_lru.h9
-rw-r--r--hicn-plugin/src/cache_policies/cs_policy.h16
-rw-r--r--hicn-plugin/src/cli.c237
-rw-r--r--hicn-plugin/src/data_fwd.h28
-rw-r--r--hicn-plugin/src/data_fwd_node.c60
-rw-r--r--hicn-plugin/src/data_input_node.c4
-rw-r--r--hicn-plugin/src/data_pcslookup.h12
-rw-r--r--hicn-plugin/src/data_pcslookup_node.c26
-rw-r--r--hicn-plugin/src/data_push_node.c326
-rw-r--r--hicn-plugin/src/error.h14
-rw-r--r--hicn-plugin/src/face_db.h30
-rw-r--r--hicn-plugin/src/faces/app/address_mgr.c20
-rw-r--r--hicn-plugin/src/faces/app/face_app_cli.c7
-rw-r--r--hicn-plugin/src/faces/app/face_cons.c18
-rw-r--r--hicn-plugin/src/faces/app/face_prod.c183
-rw-r--r--hicn-plugin/src/faces/app/face_prod.h13
-rw-r--r--hicn-plugin/src/faces/app/face_prod_node.c6
-rw-r--r--hicn-plugin/src/faces/face.c423
-rw-r--r--hicn-plugin/src/faces/face.h629
-rw-r--r--hicn-plugin/src/faces/face_cli.c20
-rw-r--r--hicn-plugin/src/faces/face_node.c (renamed from hicn-plugin/src/faces/ip/face_ip_node.c)469
-rw-r--r--hicn-plugin/src/faces/face_node.h52
-rw-r--r--hicn-plugin/src/faces/iface_node.c (renamed from hicn-plugin/src/faces/ip/iface_ip_node.c)434
-rw-r--r--hicn-plugin/src/faces/iface_node.h54
-rw-r--r--hicn-plugin/src/faces/ip/dpo_ip.c90
-rw-r--r--hicn-plugin/src/faces/ip/dpo_ip.h288
-rw-r--r--hicn-plugin/src/faces/ip/face_ip.c571
-rw-r--r--hicn-plugin/src/faces/ip/face_ip.h310
-rw-r--r--hicn-plugin/src/faces/ip/face_ip_cli.c208
-rw-r--r--hicn-plugin/src/faces/ip/face_ip_node.h40
-rw-r--r--hicn-plugin/src/faces/udp/dpo_udp.c157
-rw-r--r--hicn-plugin/src/faces/udp/dpo_udp.h289
-rw-r--r--hicn-plugin/src/faces/udp/face_udp.c449
-rw-r--r--hicn-plugin/src/faces/udp/face_udp.h356
-rw-r--r--hicn-plugin/src/faces/udp/face_udp_cli.c164
-rw-r--r--hicn-plugin/src/faces/udp/face_udp_node.c1030
-rw-r--r--hicn-plugin/src/faces/udp/face_udp_node.h35
-rw-r--r--hicn-plugin/src/faces/udp/iface_udp_node.c987
-rw-r--r--hicn-plugin/src/faces/udp/iface_udp_node.h36
-rw-r--r--hicn-plugin/src/hashtb.h73
-rw-r--r--hicn-plugin/src/hicn.api295
-rw-r--r--hicn-plugin/src/hicn.c51
-rw-r--r--hicn-plugin/src/hicn.h15
-rw-r--r--hicn-plugin/src/hicn_api.c475
-rw-r--r--hicn-plugin/src/hicn_api.h8
-rw-r--r--hicn-plugin/src/hicn_api_test.c659
-rw-r--r--hicn-plugin/src/hicn_msg_enum.h3
-rw-r--r--hicn-plugin/src/infra.h19
-rw-r--r--hicn-plugin/src/interest_hitcs.h16
-rw-r--r--hicn-plugin/src/interest_hitcs_node.c14
-rw-r--r--hicn-plugin/src/interest_hitpit.h15
-rw-r--r--hicn-plugin/src/interest_hitpit_node.c17
-rw-r--r--hicn-plugin/src/interest_pcslookup.h11
-rw-r--r--hicn-plugin/src/mapme.h125
-rw-r--r--hicn-plugin/src/mapme_ack.h5
-rw-r--r--hicn-plugin/src/mapme_ack_node.c13
-rw-r--r--hicn-plugin/src/mapme_ctrl.h44
-rw-r--r--hicn-plugin/src/mapme_ctrl_node.c82
-rw-r--r--hicn-plugin/src/mapme_eventmgr.c20
-rw-r--r--hicn-plugin/src/mapme_eventmgr.h10
-rw-r--r--hicn-plugin/src/mgmt.h5
-rw-r--r--hicn-plugin/src/params.h10
-rw-r--r--hicn-plugin/src/parser.h21
-rw-r--r--hicn-plugin/src/pcs.c3
-rw-r--r--hicn-plugin/src/pcs.h136
-rw-r--r--hicn-plugin/src/pg.h2
-rw-r--r--hicn-plugin/src/route.c784
-rw-r--r--hicn-plugin/src/route.h98
-rw-r--r--hicn-plugin/src/state.h51
-rw-r--r--hicn-plugin/src/strategies/dpo_mw.c26
-rw-r--r--hicn-plugin/src/strategies/dpo_mw.h12
-rw-r--r--hicn-plugin/src/strategies/dpo_rr.c25
-rw-r--r--hicn-plugin/src/strategies/dpo_rr.h15
-rw-r--r--hicn-plugin/src/strategies/strategy_mw.c22
-rw-r--r--hicn-plugin/src/strategies/strategy_mw.h7
-rw-r--r--hicn-plugin/src/strategies/strategy_mw_cli.c4
-rw-r--r--hicn-plugin/src/strategies/strategy_rr.c17
-rw-r--r--hicn-plugin/src/strategies/strategy_rr.h7
-rw-r--r--hicn-plugin/src/strategy.h32
-rw-r--r--hicn-plugin/src/strategy_dpo_ctx.c17
-rw-r--r--hicn-plugin/src/strategy_dpo_ctx.h64
-rw-r--r--hicn-plugin/src/strategy_dpo_manager.h55
-rw-r--r--hicn-plugin/src/strategy_node.c19
-rw-r--r--hicn-plugin/src/udp_tunnels/udp_decap.h (renamed from hicn-plugin/src/faces/ip/iface_ip_node.h)29
-rw-r--r--hicn-plugin/src/udp_tunnels/udp_decap_node.c623
-rw-r--r--hicn-plugin/src/udp_tunnels/udp_tunnel.c281
-rw-r--r--hicn-plugin/src/udp_tunnels/udp_tunnel.h114
-rw-r--r--hicn-plugin/src/utils.h21
-rw-r--r--lib/CMakeLists.txt1
-rw-r--r--lib/includes/hicn/ops.h24
-rw-r--r--lib/includes/hicn/protocol/tcp.h8
-rw-r--r--lib/src/ops.c2
-rw-r--r--lib/src/protocol/ah.c2
-rw-r--r--lib/src/protocol/icmp.c2
-rw-r--r--lib/src/protocol/ipv4.c12
-rw-r--r--lib/src/protocol/ipv6.c12
-rw-r--r--lib/src/protocol/tcp.c14
-rw-r--r--libtransport/src/core/hicn_forwarder_interface.cc2
-rw-r--r--libtransport/src/core/hicn_forwarder_interface.h2
-rw-r--r--libtransport/src/core/hicn_vapi.c45
-rw-r--r--libtransport/src/core/hicn_vapi.h6
-rw-r--r--libtransport/src/core/vpp_forwarder_interface.cc2
-rw-r--r--libtransport/src/core/vpp_forwarder_interface.h1
-rw-r--r--scripts/build-packages.sh2
119 files changed, 5901 insertions, 9991 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index afbd45f21..27d3b419e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -103,5 +103,7 @@ foreach(dir ${subdirs})
add_subdirectory(${dir})
endforeach()
+add_subdirectory(docs/doxygen)
+
include(Packager)
make_packages() \ No newline at end of file
diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt
index f5075a7aa..5f5604256 100644
--- a/apps/CMakeLists.txt
+++ b/apps/CMakeLists.txt
@@ -32,9 +32,11 @@ if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
find_package(Threads REQUIRED)
include_directories(${LIBTRANSPORT_INCLUDE_DIRS})
else()
- if (${CMAKE_SYSTEM_NAME} STREQUAL "Android")
+ if (DISABLE_SHARED_LIBRARIES)
find_package(OpenSSL REQUIRED)
- find_package(ZLIB REQUIRED)
+ if (NOT WIN32)
+ find_package(ZLIB REQUIRED)
+ endif ()
set(LIBTRANSPORT_LIBRARIES ${LIBTRANSPORT_STATIC})
else ()
set(LIBTRANSPORT_LIBRARIES ${LIBTRANSPORT_SHARED})
@@ -68,6 +70,7 @@ include(Packaging)
set(HIGET higet)
set(HTTP_PROXY hicn-http-proxy)
-
-add_subdirectory(http-proxy)
+if (NOT WIN32)
+ add_subdirectory(http-proxy)
+endif ()
add_subdirectory(higet)
diff --git a/apps/higet/higet.cc b/apps/higet/higet.cc
index 2aa42e460..7584148a9 100644
--- a/apps/higet/higet.cc
+++ b/apps/higet/higet.cc
@@ -16,9 +16,8 @@
#include <hicn/transport/http/client_connection.h>
#include <fstream>
#include <map>
-
-#include <experimental/algorithm>
-#include <experimental/functional>
+#include <algorithm>
+#include <functional>
#define ASIO_STANDALONE
#include <asio.hpp>
@@ -114,12 +113,9 @@ class ReadBytesCallbackImplementation
// read next chunk size
const char *begin = (const char *)payload->data();
const char *end = (const char *)payload->tail();
-
- using std::experimental::make_boyer_moore_searcher;
- auto it = std::experimental::search(
- begin, end,
- make_boyer_moore_searcher(chunk_separator.begin(),
- chunk_separator.end()));
+ const char *begincrlf2 = (const char *)chunk_separator.c_str();
+ const char *endcrlf2 = begincrlf2 + chunk_separator.size();
+ auto it = std::search(begin, end, begincrlf2, endcrlf2);
if (it != end) {
chunk_size_ = std::stoul(begin, 0, 16);
content_size_ += chunk_size_;
@@ -200,9 +196,15 @@ class ReadBytesCallbackImplementation
void print_bar(long value, long max_value, bool last) {
float progress = (float)value / max_value;
+#ifdef _WIN32
+ CONSOLE_SCREEN_BUFFER_INFO csbi;
+ GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
+ int barWidth = csbi.srWindow.Right - csbi.srWindow.Left + 7;
+#else
struct winsize size;
ioctl(STDOUT_FILENO, TIOCGWINSZ, &size);
int barWidth = size.ws_col - 8;
+#endif
std::cout << "[";
int pos = barWidth * progress;
@@ -252,7 +254,7 @@ long checkFileStatus(std::string file_name) {
void usage(char *program_name) {
std::cerr << "usage:" << std::endl;
std::cerr << program_name << " [option]... [url]..." << std::endl;
- std::cerr << program_name << "options:" << std::endl;
+ std::cerr << program_name << " options:" << std::endl;
std::cerr
<< "-O <out_put_path> = write documents to <out_put_file>"
<< std::endl;
@@ -303,8 +305,11 @@ int main(int argc, char **argv) {
}
}
- name = argv[optind];
+ if (!argv[optind]) {
+ usage(argv[0]);
+ }
+ name = argv[optind];
std::cerr << "Using name " << name << " and name first word "
<< conf.ipv6_first_word << std::endl;
diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/api.h b/ctrl/libhicnctrl/includes/hicn/ctrl/api.h
index c1eccbd17..bdb0c0a5f 100644
--- a/ctrl/libhicnctrl/includes/hicn/ctrl/api.h
+++ b/ctrl/libhicnctrl/includes/hicn/ctrl/api.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -603,6 +603,7 @@ typedef struct {
ip_address_t remote_addr; /* krw */
u8 len; /* krw */
u16 cost; /* .rw */
+ hc_face_t face;
} hc_route_t;
int hc_route_parse(void *in, hc_route_t *route);
diff --git a/ctrl/libhicnctrl/src/hicn_plugin_api.c b/ctrl/libhicnctrl/src/hicn_plugin_api.c
index 406f43404..0b0a9ad54 100644
--- a/ctrl/libhicnctrl/src/hicn_plugin_api.c
+++ b/ctrl/libhicnctrl/src/hicn_plugin_api.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -34,6 +34,7 @@
#include <strings.h>
#include <vapi/hicn.api.vapi.h>
#include <vapi/ip.api.vapi.h>
+#include <vapi/udp.api.vapi.h>
#include <vapi/interface.api.vapi.h>
#include <hicn/util/log.h>
#include <hicn/util/map.h>
@@ -48,6 +49,7 @@
DEFINE_VAPI_MSG_IDS_HICN_API_JSON
DEFINE_VAPI_MSG_IDS_INTERFACE_API_JSON
DEFINE_VAPI_MSG_IDS_IP_API_JSON
+DEFINE_VAPI_MSG_IDS_UDP_API_JSON
typedef struct {
vapi_ctx_t g_vapi_ctx_instance;
@@ -94,20 +96,10 @@ struct hc_sock_s {
_(hicn_api_node_params_set_reply) \
_(hicn_api_node_params_get_reply) \
_(hicn_api_node_stats_get_reply) \
- _(hicn_api_face_add) \
- _(hicn_api_face_add_reply) \
- _(hicn_api_face_del) \
- _(hicn_api_face_del_reply) \
_(hicn_api_face_get) \
_(hicn_api_faces_details) \
_(hicn_api_face_stats_details) \
_(hicn_api_face_get_reply) \
- _(hicn_api_route_nhops_add) \
- _(hicn_api_route_nhops_add_reply) \
- _(hicn_api_route_del) \
- _(hicn_api_route_del_reply) \
- _(hicn_api_route_nhop_del) \
- _(hicn_api_route_nhop_del_reply) \
_(hicn_api_route_get) \
_(hicn_api_route_get_reply) \
_(hicn_api_routes_details) \
@@ -115,6 +107,7 @@ struct hc_sock_s {
_(hicn_api_strategy_get) \
_(hicn_api_strategy_get_reply)
+
typedef vapi_type_msg_header2_t hc_msg_header_t;
typedef union {
@@ -622,12 +615,29 @@ int hc_connection_set_admin_state_async(hc_sock_t *s,
* Routes
*----------------------------------------------------------------------------*/
+vapi_error_e create_udp_tunnel_cb( vapi_ctx_t ctx,
+ void *callback_ctx,
+ vapi_error_e rv,
+ bool is_last,
+ vapi_payload_hicn_api_udp_tunnel_add_del_reply *reply) {
+ if (reply == NULL || rv != VAPI_OK)
+ return rv;
+
+ if (reply->retval != VAPI_OK)
+ return reply->retval;
+
+ u32 * uei = (u32*) callback_ctx;
+ *uei = reply->uei;
+
+ return reply->retval;
+}
+
/* ROUTE CREATE */
vapi_error_e parse_route_create( vapi_ctx_t ctx,
void *callback_ctx,
vapi_error_e rv,
bool is_last,
- vapi_payload_hicn_api_route_nhops_add_reply *reply) {
+ vapi_payload_ip_route_add_del_reply *reply) {
if (reply == NULL || rv != VAPI_OK)
return rv;
@@ -637,31 +647,133 @@ vapi_error_e parse_route_create( vapi_ctx_t ctx,
return reply->retval;
}
+vapi_error_e hicn_enable_cb( vapi_ctx_t ctx,
+ void *callback_ctx,
+ vapi_error_e rv,
+ bool is_last,
+ vapi_payload_hicn_api_enable_disable_reply *reply) {
+ if (reply == NULL || rv != VAPI_OK)
+ return rv;
+
+ return reply->retval;
+}
+
int _hc_route_create(hc_sock_t *s, hc_route_t *route, bool async) {
if (!IS_VALID_FAMILY(route->family)) return -1;
+ int ret;
vapi_lock();
- vapi_msg_hicn_api_route_nhops_add *hicnp_msg;
- hicnp_msg = vapi_alloc_hicn_api_route_nhops_add(s->g_vapi_ctx_instance);
- if (!hicnp_msg) return VAPI_ENOMEM;
+ vapi_msg_ip_route_add_del *hicnp_msg = vapi_alloc_ip_route_add_del(s->g_vapi_ctx_instance, 1);
+ hicnp_msg->payload.is_add = 1;
if (route->family == AF_INET) {
- memcpy(&hicnp_msg->payload.prefix.address.un.ip4[0], &route->remote_addr.v4, 4);
+ memcpy(&hicnp_msg->payload.route.prefix.address.un.ip4[0], &route->remote_addr.v4, 4);
+ hicnp_msg->payload.route.prefix.address.af = ADDRESS_IP4;
}
else {
- memcpy(&hicnp_msg->payload.prefix.address.un.ip6[0], &route->remote_addr.v6, 16);
+ memcpy(&hicnp_msg->payload.route.prefix.address.un.ip6[0], &route->remote_addr.v6, 16);
+ hicnp_msg->payload.route.prefix.address.af = ADDRESS_IP6;
}
- hicnp_msg->payload.prefix.address.af =
- route->family == AF_INET ? ADDRESS_IP4 : ADDRESS_IP6;
- hicnp_msg->payload.prefix.len = route->len;
- hicnp_msg->payload.face_ids[0] = route->face_id;
- hicnp_msg->payload.n_faces = 1;
- vapi_error_e ret = vapi_hicn_api_route_nhops_add(s->g_vapi_ctx_instance, hicnp_msg, parse_route_create, NULL);
+ hicnp_msg->payload.route.prefix.len = route->len;
+
+ hicnp_msg->payload.route.paths[0].sw_if_index = ~0;
+ hicnp_msg->payload.route.paths[0].table_id = 0;
+
+ hc_face_t *face = &(route->face);
+ switch (face->face.type) {
+ case FACE_TYPE_HICN:
+ {
+ if (ip46_address_is_ip4((ip46_address_t *)(&(face->face.remote_addr)))) {
+ memcpy(&(hicnp_msg->payload.route.paths[0].nh.address.ip4), &face->face.remote_addr.v4, sizeof(ip4_address_t));
+ hicnp_msg->payload.route.paths[0].proto = FIB_API_PATH_NH_PROTO_IP4;
+ }
+ else{
+ memcpy(&(hicnp_msg->payload.route.paths[0].nh.address.ip6), &face->face.remote_addr.v6, sizeof(ip6_address_t));
+ hicnp_msg->payload.route.paths[0].proto = FIB_API_PATH_NH_PROTO_IP6;
+ }
+
+ hicnp_msg->payload.route.paths[0].type = FIB_API_PATH_FLAG_NONE;
+ hicnp_msg->payload.route.paths[0].flags = FIB_API_PATH_FLAG_NONE;
+
+ break;
+ }
+ case FACE_TYPE_UDP:
+ {
+ vapi_msg_hicn_api_udp_tunnel_add_del *msg = NULL;
+ u32 uei = ~0;
+
+ if (ip46_address_is_ip4((ip46_address_t *)(&(face->face.remote_addr))) &&
+ ip46_address_is_ip4((ip46_address_t *)(&(face->face.local_addr)))) {
+
+ msg = vapi_alloc_hicn_api_udp_tunnel_add_del(s->g_vapi_ctx_instance);
+ memcpy(msg->payload.src_addr.un.ip4, &face->face.local_addr.v4, sizeof(ip4_address_t));
+ msg->payload.src_addr.af = ADDRESS_IP4;
+
+ memcpy(msg->payload.dst_addr.un.ip4, &face->face.remote_addr.v4, sizeof(ip4_address_t));
+ msg->payload.dst_addr.af = ADDRESS_IP4;
+
+ } else if (!ip46_address_is_ip4((ip46_address_t *)(&(route->face.face.remote_addr))) &&
+ !ip46_address_is_ip4((ip46_address_t *)(&(route->face.face.local_addr)))) {
+
+ msg = vapi_alloc_hicn_api_udp_tunnel_add_del(s->g_vapi_ctx_instance);
+ memcpy(msg->payload.src_addr.un.ip6, &face->face.local_addr.v6, sizeof(ip6_address_t));
+ msg->payload.src_addr.af = ADDRESS_IP4;
+
+ memcpy(msg->payload.dst_addr.un.ip6, &face->face.remote_addr.v6, sizeof(ip6_address_t));
+ msg->payload.dst_addr.af = ADDRESS_IP6;
+
+ } else {
+ //NOT IMPLEMENTED
+ ret = -1;
+ goto done;
+ }
+
+ msg->payload.src_port = face->face.local_port;
+ msg->payload.dst_port = face->face.remote_port;
+ msg->payload.is_add = 1;
+
+ int ret = vapi_hicn_api_udp_tunnel_add_del(s->g_vapi_ctx_instance, msg, create_udp_tunnel_cb, &uei);
+
+ if(ret) {
+ vapi_msg_free(s->g_vapi_ctx_instance, hicnp_msg);
+ goto done;
+ }
+
+ hicnp_msg->payload.route.paths[0].type = FIB_API_PATH_TYPE_UDP_ENCAP;
+ hicnp_msg->payload.route.paths[0].flags = FIB_API_PATH_FLAG_NONE;
+ hicnp_msg->payload.route.paths[0].nh.obj_id = uei;
+ break;
+ }
+ default:
+ ret = -1;
+ goto done;
+ }
+
+ ret = vapi_ip_route_add_del(s->g_vapi_ctx_instance, hicnp_msg, parse_route_create, NULL);
+
+ if (ret)
+ goto done;
+
+ vapi_msg_hicn_api_enable_disable *msg = vapi_alloc_hicn_api_enable_disable(s->g_vapi_ctx_instance);
+
+ if (route->family == AF_INET) {
+ memcpy(&msg->payload.prefix.address.un.ip4[0], &route->remote_addr.v4, 4);
+ msg->payload.prefix.address.af = ADDRESS_IP4;
+ }
+ else {
+ memcpy(&msg->payload.prefix.address.un.ip6[0], &route->remote_addr.v6, 16);
+ msg->payload.prefix.address.af = ADDRESS_IP6;
+ }
+
+ msg->payload.prefix.len = route->len;
+ msg->payload.enable_disable = 1;
+
+ ret = vapi_hicn_api_enable_disable(s->g_vapi_ctx_instance, msg, hicn_enable_cb, NULL);
+done:
vapi_unlock();
return ret;
-
}
int hc_route_create(hc_sock_t *s, hc_route_t *route) {
@@ -677,13 +789,10 @@ vapi_error_e parse_route_delete( vapi_ctx_t ctx,
void *callback_ctx,
vapi_error_e rv,
bool is_last,
- vapi_payload_hicn_api_route_nhop_del_reply *reply) {
+ vapi_payload_ip_route_add_del_reply *reply) {
if (reply == NULL || rv != VAPI_OK)
return rv;
- if (reply->retval != VAPI_OK)
- return reply->retval;
-
return reply->retval;
}
@@ -691,20 +800,56 @@ int _hc_route_delete(hc_sock_t *s, hc_route_t *route, bool async) {
if (!IS_VALID_FAMILY(route->family)) return -1;
vapi_lock();
- vapi_msg_hicn_api_route_nhop_del *hicnp_msg;
- hicnp_msg = vapi_alloc_hicn_api_route_nhop_del(s->g_vapi_ctx_instance);
+ vapi_msg_ip_route_add_del *hicnp_msg = vapi_alloc_ip_route_add_del(s->g_vapi_ctx_instance, 1);
+
+ hicnp_msg->payload.is_add = 0;
+ if (route->family == AF_INET) {
+ memcpy(&hicnp_msg->payload.route.prefix.address.un.ip4[0], &route->remote_addr.v4, 4);
+ hicnp_msg->payload.route.prefix.address.af = ADDRESS_IP4;
+ }
+ else {
+ memcpy(&hicnp_msg->payload.route.prefix.address.un.ip6[0], &route->remote_addr.v6, 16);
+ hicnp_msg->payload.route.prefix.address.af = ADDRESS_IP6;
+ }
- if (!hicnp_msg) return VAPI_ENOMEM;
+ hicnp_msg->payload.route.prefix.len = route->len;
- memcpy(&hicnp_msg->payload.prefix.address.un.ip6[0], &route->remote_addr, 16);
- hicnp_msg->payload.prefix.address.af =
- route->family == AF_INET ? ADDRESS_IP4 : ADDRESS_IP6;
- hicnp_msg->payload.prefix.len = route->len;
- hicnp_msg->payload.faceid = route->face_id;
+ hicnp_msg->payload.route.paths[0].sw_if_index = ~0;
+ hicnp_msg->payload.route.paths[0].table_id = 0;
+
+ hc_face_t *face = &(route->face);
+ switch (face->face.type) {
+ case FACE_TYPE_HICN:
+ {
+ if (ip46_address_is_ip4((ip46_address_t *)(&(face->face.remote_addr)))) {
+ memcpy(&(hicnp_msg->payload.route.paths[0].nh.address.ip4), &face->face.remote_addr.v4, sizeof(ip4_address_t));
+ hicnp_msg->payload.route.paths[0].proto = FIB_API_PATH_NH_PROTO_IP4;
+ }
+ else{
+ memcpy(&(hicnp_msg->payload.route.paths[0].nh.address.ip6), &face->face.remote_addr.v6, sizeof(ip6_address_t));
+ hicnp_msg->payload.route.paths[0].proto = FIB_API_PATH_NH_PROTO_IP6;
+ }
+
+ hicnp_msg->payload.route.paths[0].type = FIB_API_PATH_FLAG_NONE;
+ hicnp_msg->payload.route.paths[0].flags = FIB_API_PATH_FLAG_NONE;
+
+ break;
+ }
+ case FACE_TYPE_UDP:
+ {
+ hicnp_msg->payload.route.paths[0].type = FIB_API_PATH_TYPE_UDP_ENCAP;
+ hicnp_msg->payload.route.paths[0].flags = FIB_API_PATH_FLAG_NONE;
+ hicnp_msg->payload.route.paths[0].nh.obj_id = face->face.netdevice.index;
+ break;
+ }
+ default:
+ return -1;
+ }
+
+ vapi_error_e ret = vapi_ip_route_add_del(s->g_vapi_ctx_instance, hicnp_msg, parse_route_delete, NULL);
- int retval = vapi_hicn_api_route_nhop_del(s->g_vapi_ctx_instance, hicnp_msg, parse_route_delete, NULL);
vapi_unlock();
- return retval;
+ return ret;
}
int hc_route_delete(hc_sock_t *s, hc_route_t *route) {
@@ -715,18 +860,121 @@ int hc_route_delete_async(hc_sock_t *s, hc_route_t *route) {
return _hc_route_delete(s, route, true);
}
+vapi_error_e parse_udp_encap_list( vapi_ctx_t ctx,
+ void *callback_ctx,
+ vapi_error_e rv,
+ bool is_last,
+ vapi_payload_udp_encap_details *reply) {
+ if (reply == NULL || rv != VAPI_OK)
+ return rv;
+
+ hc_face_t * face = (hc_face_t *)callback_ctx;
+
+ if (face->face.netdevice.index == reply->udp_encap.id)
+ {
+ switch(reply->udp_encap.src_ip.af) {
+ case ADDRESS_IP4:
+ {
+ memcpy(&face->face.local_addr.v4, &(reply->udp_encap.src_ip.un.ip4), sizeof(ip4_address_t));
+ memcpy(&face->face.remote_addr.v4, &(reply->udp_encap.dst_ip.un.ip4), sizeof(ip4_address_t));
+ break;
+ }
+ case ADDRESS_IP6:
+ {
+ memcpy(&face->face.local_addr.v6, &(reply->udp_encap.src_ip.un.ip6), sizeof(ip6_address_t));
+ memcpy(&face->face.remote_addr.v6, &(reply->udp_encap.dst_ip.un.ip6), sizeof(ip6_address_t));
+ break;
+ }
+ default:
+ break;
+ }
+
+ face->face.local_port = reply->udp_encap.src_port;
+ face->face.remote_port = reply->udp_encap.dst_port;
+ }
+ return rv;
+}
+
+int fill_face_with_info(hc_face_t * face, vapi_type_fib_path *path, hc_sock_t *s) {
+ switch(path->type){
+ case FIB_API_PATH_FLAG_NONE:
+ {
+ face->face.type = FACE_TYPE_HICN;
+ switch(path->proto){
+ case FIB_API_PATH_NH_PROTO_IP4:
+ memcpy(&face->face.remote_addr.v4, &(path->nh.address.ip4), sizeof(ip4_address_t));
+ break;
+ case FIB_API_PATH_NH_PROTO_IP6:
+ memcpy(&face->face.remote_addr.v6, &(path->nh.address.ip6), sizeof(ip6_address_t));
+ break;
+ default:
+ break;
+ }
+ face->face.netdevice.index = path->sw_if_index;
+ }
+ break;
+ case FIB_API_PATH_TYPE_UDP_ENCAP:
+ {
+ face->face.type = FACE_TYPE_UDP;
+ face->face.netdevice.index = clib_net_to_host_u32(path->nh.obj_id);
+ //vapi_msg_udp_encap_dump *msg;
+ //msg = vapi_alloc_udp_encap_dump(s->g_vapi_ctx_instance);
+ //vapi_udp_encap_dump(s->g_vapi_ctx_instance, msg, parse_udp_encap_list, face);
+ }
+ break;
+ default:
+ return -1;
+ }
+ return 0;
+}
+
/* ROUTE LIST */
+typedef struct hicn_route_socket_s {
+ hc_data_t *data;
+ hc_sock_t *s;
+} hicn_route_socket_t;
+
vapi_error_e parse_route_list( vapi_ctx_t ctx,
void *callback_ctx,
vapi_error_e rv,
bool is_last,
- vapi_payload_hicn_api_routes_details *reply) {
+ vapi_payload_ip_route_details *reply) {
if (reply == NULL || rv != VAPI_OK)
return rv;
- if (reply->retval != VAPI_OK)
- return reply->retval;
+ hicn_route_socket_t *rs = (hicn_route_socket_t *)callback_ctx;
+ hc_data_t *data = rs->data;
+
+ u8 found = false;
+ for (int j = 0; j < reply->route.n_paths; j++){
+ for (int i = 0; i < data->size && !found; i++) {
+ hc_route_t * route = &((hc_route_t*)(data->buffer))[i];
+
+ if(ip46_address_is_ip4((ip46_address_t *)&(route->remote_addr)) &&
+ memcmp(route->remote_addr.v4.as_u8, reply->route.prefix.address.un.ip4, sizeof(ip4_address_t)) == 0 &&
+ route->len == reply->route.prefix.len && route->face_id == ~0) {
+ fill_face_with_info(&(route->face), &reply->route.paths[j], rs->s);
+ found = true;
+ } else if (memcmp(route->remote_addr.v6.as_u8, reply->route.prefix.address.un.ip6, sizeof(ip6_address_t)) == 0 &&
+ route->len == reply->route.prefix.len && route->face_id == ~0) {
+ fill_face_with_info(&(route->face), &reply->route.paths[j], rs->s);
+ found = true;
+ }
+ }
+ }
+
+ return rv;
+}
+
+vapi_error_e parse_hicn_route_list( vapi_ctx_t ctx,
+ void *callback_ctx,
+ vapi_error_e rv,
+ bool is_last,
+ vapi_payload_hicn_api_routes_details *reply) {
+
+ if (reply == NULL || rv != VAPI_OK)
+ return rv;
hc_data_t *data = (hc_data_t *)callback_ctx;
@@ -742,7 +990,7 @@ vapi_error_e parse_route_list( vapi_ctx_t ctx,
for (int i = 0; i < reply->nfaces; i++) {
hc_route_t * route = &((hc_route_t*)(data->buffer))[data->current];
- route->face_id = reply->faceids[i];
+ route->face_id = ~0;
route->cost = 1;
route->len = reply->prefix.len;
if (reply->prefix.address.af == ADDRESS_IP6)
@@ -757,13 +1005,14 @@ vapi_error_e parse_route_list( vapi_ctx_t ctx,
data->current++;
}
- return reply->retval;
+ return rv;
}
int _hc_route_list(hc_sock_t *s, hc_data_t **pdata, bool async) {
vapi_lock();
- vapi_msg_hicn_api_routes_dump *hicnp_msg;
- hicnp_msg = vapi_alloc_hicn_api_routes_dump(s->g_vapi_ctx_instance);
+
+ vapi_msg_hicn_api_routes_dump *msg;
+ msg = vapi_alloc_hicn_api_routes_dump(s->g_vapi_ctx_instance);
hc_data_t *data = hc_data_create(0, sizeof(hc_route_t),NULL);
int ret = VAPI_OK;
@@ -781,7 +1030,28 @@ int _hc_route_list(hc_sock_t *s, hc_data_t **pdata, bool async) {
goto err_free;
}
- ret = vapi_hicn_api_routes_dump(s->g_vapi_ctx_instance, hicnp_msg, parse_route_list, data);
+ ret = vapi_hicn_api_routes_dump(s->g_vapi_ctx_instance, msg, parse_hicn_route_list, data);
+
+ if (ret != VAPI_OK)
+ goto err_free;
+
+ vapi_msg_ip_route_dump *hicnp_msg;
+ hicnp_msg = vapi_alloc_ip_route_dump(s->g_vapi_ctx_instance);
+ hicnp_msg->payload.table.table_id = 0;
+ hicnp_msg->payload.table.is_ip6 = 1;
+
+ hicn_route_socket_t ctx = {
+ .data = data,
+ .s = s,
+ };
+
+ ret = vapi_ip_route_dump(s->g_vapi_ctx_instance, hicnp_msg, parse_route_list, &ctx);
+
+ hicnp_msg = vapi_alloc_ip_route_dump(s->g_vapi_ctx_instance);
+ hicnp_msg->payload.table.table_id = 0;
+ hicnp_msg->payload.table.is_ip6 = 0;
+
+ ret = vapi_ip_route_dump(s->g_vapi_ctx_instance, hicnp_msg, parse_route_list, &ctx);
if (ret != VAPI_OK)
goto err_free;
@@ -880,278 +1150,23 @@ int hc_connection_to_local_listener(const hc_connection_t *connection,
return 0;
}
-/* FACE CREATE */
-vapi_error_e parse_face_create( vapi_ctx_t ctx,
- void *callback_ctx,
- vapi_error_e rv,
- bool is_last,
- vapi_payload_hicn_api_face_add_reply *reply) {
-
- if (reply == NULL || rv != VAPI_OK)
- return rv;
-
- if (reply->retval != VAPI_OK)
- return reply->retval;
-
- hc_data_t *data = (hc_data_t *)callback_ctx;
-
- hc_face_t *output = (hc_face_t *)data->buffer;
-
- output->id = reply->faceid;
- return reply->retval;
-}
-
int hc_face_create(hc_sock_t *s, hc_face_t *face) {
-
- vapi_lock();
- vapi_msg_hicn_api_face_add *hicnp_msg;
- hicnp_msg = vapi_alloc_hicn_api_face_add(s->g_vapi_ctx_instance);
-
- int retval = VAPI_OK;
- if (!hicnp_msg) {
- retval = VAPI_ENOMEM;
- goto END;
- }
-
- switch(face->face.type) {
- case FACE_TYPE_HICN:
- {
- u8 check = ip46_address_is_ip4((ip46_address_t *)&(face->face.local_addr)) == ip46_address_is_ip4((ip46_address_t *)&(face->face.remote_addr));
- if (!check) {
- retval = -1;
- goto END;
- }
-
- hicnp_msg->payload.type = IP_FACE;
- if (ip46_address_is_ip4((ip46_address_t *)&(face->face.local_addr)))
- {
- memcpy(hicnp_msg->payload.face.ip.local_addr.un.ip4, face->face.local_addr.v4.as_u8, 4);
- memcpy(hicnp_msg->payload.face.ip.remote_addr.un.ip4, face->face.remote_addr.v4.as_u8, 4);
- hicnp_msg->payload.face.ip.local_addr.af = ADDRESS_IP4;
- hicnp_msg->payload.face.ip.remote_addr.af = ADDRESS_IP4;
- }
- else
- {
- memcpy(hicnp_msg->payload.face.ip.local_addr.un.ip6, face->face.local_addr.v6.as_u8, 16);
- memcpy(hicnp_msg->payload.face.ip.remote_addr.un.ip6, face->face.remote_addr.v6.as_u8, 16);
- hicnp_msg->payload.face.ip.local_addr.af = ADDRESS_IP6;
- hicnp_msg->payload.face.ip.remote_addr.af = ADDRESS_IP6;
- }
- hicnp_msg->payload.face.ip.swif = face->face.netdevice.index;
- memcpy(hicnp_msg->payload.face.ip.if_name, face->face.netdevice.name, IFNAMSIZ);
- break;
- }
- case FACE_TYPE_UDP:
- {
- u8 check = ip46_address_is_ip4((ip46_address_t *)&(face->face.local_addr)) == ip46_address_is_ip4((ip46_address_t *)&(face->face.remote_addr));
- if (!check) {
- retval = -1;
- goto END;
- }
-
- hicnp_msg->payload.type = UDP_FACE;
- if (ip46_address_is_ip4((ip46_address_t *)&(face->face.local_addr)))
- {
- memcpy(hicnp_msg->payload.face.udp.local_addr.un.ip4, face->face.local_addr.v4.as_u8, 4);
- memcpy(hicnp_msg->payload.face.udp.remote_addr.un.ip4, face->face.remote_addr.v4.as_u8, 4);
- hicnp_msg->payload.face.udp.local_addr.af = ADDRESS_IP4;
- hicnp_msg->payload.face.udp.remote_addr.af = ADDRESS_IP4;
- }
- else
- {
- memcpy(hicnp_msg->payload.face.udp.local_addr.un.ip6, face->face.local_addr.v6.as_u8, 16);
- memcpy(hicnp_msg->payload.face.udp.remote_addr.un.ip6, face->face.remote_addr.v6.as_u8, 16);
- hicnp_msg->payload.face.udp.local_addr.af = ADDRESS_IP6;
- hicnp_msg->payload.face.udp.remote_addr.af = ADDRESS_IP6;
- }
- hicnp_msg->payload.face.udp.lport = face->face.local_port;
- hicnp_msg->payload.face.udp.rport = face->face.remote_port;
- hicnp_msg->payload.face.udp.swif = face->face.netdevice.index;
- memcpy(hicnp_msg->payload.face.udp.if_name, face->face.netdevice.name, IFNAMSIZ);
- break;
- }
- default:
- {
- retval = -1;
- goto END;
- }
- }
-
- hc_data_t *data = hc_data_create(0, sizeof(hc_face_t),NULL);
-
- if (!data) {
- retval = -1;
- goto END;
- }
-
- data->buffer = malloc(sizeof(hc_face_t));
- data->out_element_size = sizeof(hc_face_t);
-
- if (!data->buffer) {
- free (data);
- retval = -1;
- goto END;
- }
-
- retval = vapi_hicn_api_face_add(s->g_vapi_ctx_instance, hicnp_msg, parse_face_create, data);
-
- if (retval != VAPI_OK)
- goto END;
-
- face->id = ((hc_face_t *)data->buffer)->id;
-
- END:
- vapi_unlock();
- return retval;
-}
-
-vapi_error_e parse_face_delete( vapi_ctx_t ctx,
- void *callback_ctx,
- vapi_error_e rv,
- bool is_last,
- vapi_payload_hicn_api_face_del_reply *reply) {
-
- if (reply == NULL || rv != VAPI_OK)
- return rv;
-
- return reply->retval;
+ ERROR("Face creation implemented.");
+ return -1;
}
int hc_face_delete(hc_sock_t *s, hc_face_t *face) {
- vapi_msg_hicn_api_face_del *hicnp_msg;
- vapi_lock();
- hicnp_msg = vapi_alloc_hicn_api_face_del(s->g_vapi_ctx_instance);
-
- if (!hicnp_msg) return VAPI_ENOMEM;
-
- hicnp_msg->payload.faceid = face->id;
-
- int retval = vapi_hicn_api_face_del(s->g_vapi_ctx_instance, hicnp_msg, parse_face_delete, NULL);
- vapi_unlock();
- return retval;
+ ERROR("Face deletion not implemented.");
+ return -1;
}
/* FACE LIST */
-vapi_error_e parse_face_list( vapi_ctx_t ctx,
- void *callback_ctx,
- vapi_error_e rv,
- bool is_last,
- vapi_payload_hicn_api_faces_details *reply) {
-
- if (reply == NULL || rv != VAPI_OK)
- return rv;
-
- if (reply->retval != VAPI_OK)
- return reply->retval;
-
- hc_data_t *data = (hc_data_t *)callback_ctx;
-
- if (data->size == data->current) {
- int new_size = data->size *2;
- data->buffer = realloc(data->buffer, sizeof(hc_face_t) * (new_size));
- if (!data->buffer)
- return VAPI_ENOMEM;
-
- data->size =new_size;
- }
-
- int retval = VAPI_OK;
-
- hc_face_t * face = &((hc_face_t *)(data->buffer))[data->current];
- switch(reply->type)
- {
- case IP_FACE:
- {
- if (reply->face.ip.local_addr.af == ADDRESS_IP4)
- {
- memcpy(face->face.local_addr.v4.as_u8, reply->face.ip.local_addr.un.ip4, IPV4_ADDR_LEN);
- memcpy(face->face.remote_addr.v4.as_u8, reply->face.ip.remote_addr.un.ip4, IPV4_ADDR_LEN);
- }
- else
- {
- memcpy(face->face.local_addr.v6.as_u8, reply->face.ip.local_addr.un.ip6, IPV6_ADDR_LEN);
- memcpy(face->face.remote_addr.v6.as_u8, reply->face.ip.remote_addr.un.ip6, IPV6_ADDR_LEN);
- }
- face->face.type = FACE_TYPE_HICN;
- face->id = reply->faceid;
- face->face.netdevice.index = reply->face.ip.swif;
- memcpy(face->face.netdevice.name, reply->face.ip.if_name, IFNAMSIZ);
- break;
- }
- case UDP_FACE:
- {
- if (reply->face.ip.local_addr.af == ADDRESS_IP4)
- {
- memcpy(face->face.local_addr.v4.as_u8, reply->face.udp.local_addr.un.ip4, IPV4_ADDR_LEN);
- memcpy(face->face.remote_addr.v4.as_u8, reply->face.udp.remote_addr.un.ip4, IPV4_ADDR_LEN);
- }
- else
- {
- memcpy(face->face.local_addr.v6.as_u8, reply->face.udp.local_addr.un.ip6, IPV6_ADDR_LEN);
- memcpy(face->face.remote_addr.v6.as_u8, reply->face.udp.remote_addr.un.ip6, IPV6_ADDR_LEN);
- }
- face->face.local_port = reply->face.udp.lport;
- face->face.remote_port = reply->face.udp.rport;
- face->face.type = FACE_TYPE_UDP;
- face->id = reply->faceid;
- face->face.netdevice.index = reply->face.udp.swif;
- memcpy(face->face.netdevice.name, reply->face.udp.if_name, IFNAMSIZ);
- break;
- }
- default:
- retval = -1;
- }
- if (!retval)
- data->current++;
-
- return reply->retval;
-}
-
int hc_face_list(hc_sock_t *s, hc_data_t **pdata) {
- vapi_lock();
- vapi_msg_hicn_api_faces_dump *hicnp_msg;
- hicnp_msg = vapi_alloc_hicn_api_faces_dump(s->g_vapi_ctx_instance);
-
- int retval = 0;
- if (!hicnp_msg) {
- retval = VAPI_ENOMEM;
- goto END;
- }
- hc_data_t *data = hc_data_create(0, sizeof(hc_face_t),NULL);
-
- if (!data) {
- retval = -1;
- goto END;
- }
-
- data->buffer = malloc(sizeof(hc_face_t));
- data->size = 1;
-
- if (!data->buffer) {
- free (data);
- retval = -1;
- goto err;
- }
-
-
- retval = vapi_hicn_api_faces_dump(s->g_vapi_ctx_instance, hicnp_msg, parse_face_list, data);
- *pdata = data;
-
- if (retval != VAPI_OK)
- goto err;
-
- data->size = data->current;
- vapi_unlock();
- return retval;
-
- err:
- free(data);
- END:
- vapi_unlock();
- return retval;
+ERROR("Face list not implemented.");
+return -1;
}
int hc_connection_parse_to_face(void *in, hc_face_t *face) { return 0; }
diff --git a/ctrl/sysrepo-plugins/hicn-plugin/plugin/hicn_plugin.c b/ctrl/sysrepo-plugins/hicn-plugin/plugin/hicn_plugin.c
index dc3ac16d4..bbcc2e9bf 100644
--- a/ctrl/sysrepo-plugins/hicn-plugin/plugin/hicn_plugin.c
+++ b/ctrl/sysrepo-plugins/hicn-plugin/plugin/hicn_plugin.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019 Cisco and/or its affiliates.
+ * Copyright (c) 2019-2020 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:
@@ -38,8 +38,10 @@ int sr_plugin_init_cb(sr_session_ctx_t *session, void **private_ctx) {
// HICN subscribe
hicn_subscribe_events(session, &subscription);
+ //sr_subscription_ctx_t *subscription2 = NULL;
+
// IETF subscribe
- ietf_subscribe_events(session, &subscription);
+ //ietf_subscribe_events(session, &subscription2);
/* set subscription as our private context */
diff --git a/ctrl/sysrepo-plugins/hicn-plugin/plugin/ietf/ietf_interface.c b/ctrl/sysrepo-plugins/hicn-plugin/plugin/ietf/ietf_interface.c
index b46b38b89..3e0c90cf9 100644
--- a/ctrl/sysrepo-plugins/hicn-plugin/plugin/ietf/ietf_interface.c
+++ b/ctrl/sysrepo-plugins/hicn-plugin/plugin/ietf/ietf_interface.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016 Cisco and/or its affiliates.
+ * Copyright (c) 2016-2020 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:
@@ -442,7 +442,7 @@ ietf_interface_ipv46_address_change_cb(sr_session_ctx_t *session, const char *mo
sr_change_oper_t op = SR_OP_CREATED;
sr_val_t *old_val = NULL;
sr_val_t *new_val = NULL;
- sr_xpath_ctx_t xpath_ctx = { 0, };
+ sr_xpath_ctx_t xpath_ctx = { 0 };
bool is_ipv6 = false, has_addr = false, has_prefix = false;
uint8_t addr[16] = { 0, };
uint8_t prefix = 0;
@@ -570,7 +570,8 @@ int ietf_subscribe_events(sr_session_ctx_t *session,
goto error;
}
- rc = sr_module_change_subscribe(session, "ietf-interfaces","/ietf-interfaces:interfaces/interface/ietf-ip:ipv4/address", ietf_interface_ipv46_address_change_cb,
+ //rc = sr_module_change_subscribe(session, "ietf-interfaces","/ietf-interfaces:interfaces/interface/ietf-ip:ipv4/address", ietf_interface_ipv46_address_change_cb,
+ rc = sr_module_change_subscribe(session, "ietf-interfaces","/ietf-interfaces:interfaces", ietf_interface_ipv46_address_change_cb,
NULL,
99, SR_SUBSCR_CTX_REUSE | SR_SUBSCR_ENABLED, subscription);
@@ -579,9 +580,9 @@ int ietf_subscribe_events(sr_session_ctx_t *session,
goto error;
}
- rc = sr_module_change_subscribe(session, "ietf-interfaces","/ietf-interfaces:interfaces/interface/ietf-ip:ipv6/address", ietf_interface_ipv46_address_change_cb,
- NULL,
- 98, SR_SUBSCR_CTX_REUSE | SR_SUBSCR_ENABLED, subscription);
+ //rc = sr_module_change_subscribe(session, "ietf-interfaces","/ietf-interfaces:interfaces/interface/ietf-ip:ipv6/address", ietf_interface_ipv46_address_change_cb,
+ // NULL,
+ // 98, SR_SUBSCR_CTX_REUSE | SR_SUBSCR_ENABLED, subscription);
if (rc != SR_ERR_OK) {
SRP_LOG_DBGMSG("Problem in subscription /ietf-interfaces:interfaces/interface/ietf-ip:ipv6/address\n");
diff --git a/ctrl/sysrepo-plugins/hicn-plugin/plugin/mainpage.dox b/ctrl/sysrepo-plugins/hicn-plugin/plugin/mainpage.dox
index dc4289379..978578039 100644
--- a/ctrl/sysrepo-plugins/hicn-plugin/plugin/mainpage.dox
+++ b/ctrl/sysrepo-plugins/hicn-plugin/plugin/mainpage.dox
@@ -29,47 +29,13 @@ fi
*Here you can find different examples to run RPC in the yang-model.
```
-<face-ip-add xmlns="urn:sysrepo:hicn">
- <lip4>192.168.1.10</lip4>
- <lip6>-1</lip6>
- <rip4>192.168.1.1</rip4>
- <rip6>-1</rip6>
- <swif>0</swif>
-</face-ip-add>
-
-<route-nhops-add xmlns="urn:sysrepo:hicn">
- <ip4>192.168.1.1</ip4>
- <ip6>-1</ip6>
- <len>24</len>
- <face_ids0>0</face_ids0>
- <face_ids1>0</face_ids1>
- <face_ids2>0</face_ids2>
- <face_ids3>0</face_ids3>
- <face_ids4>0</face_ids4>
- <face_ids5>0</face_ids5>
- <face_ids6>0</face_ids6>
- <n_faces>1</n_faces>
-</route-nhops-add>
-
-<route-nhops-del xmlns="urn:sysrepo:hicn">
- <ip4>192.168.1.1</ip4>
- <ip6>-1</ip6>
- <len>24</len>
- <faceid>0</faceid>
-</route-nhops-del>
-
-
-<face-ip-del xmlns="urn:sysrepo:hicn">
- <faceid>0</faceid>
-</face-ip-del>
-
-
-<punting-del-ip xmlns="urn:sysrepo:hicn">
- <ip4>192.168.0.1</ip4>
- <ip6>-1</ip6>
- <len>24</len>
- <swif>0</swif>
-</punting-del-ip>
+<hicn-enable xmlns="urn:sysrepo:hicn">
+ <prefix>b001::/64</prefix>
+</hicn-enable>
+
+<hicn-disable xmlns="urn:sysrepo:hicn">
+ <prefix>b001::/64</prefix>
+</hicn-disable>
```
*/
diff --git a/ctrl/sysrepo-plugins/hicn-plugin/plugin/model/hicn_model.c b/ctrl/sysrepo-plugins/hicn-plugin/plugin/model/hicn_model.c
index 2a486f599..63685e10a 100644
--- a/ctrl/sysrepo-plugins/hicn-plugin/plugin/model/hicn_model.c
+++ b/ctrl/sysrepo-plugins/hicn-plugin/plugin/model/hicn_model.c
@@ -1,1134 +1,875 @@
/*
-* Copyright (c) 2019-2020 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.
-*/
-
-
+ * Copyright (c) 2019-2020 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.
+ */
/** @file hicn_model.c
* @brief This file contains implementations of the main calls
*/
-
#define _GNU_SOURCE
-#include <stdio.h>
-#include <malloc.h>
-#include <sysrepo/xpath.h>
#include <inttypes.h>
-#include <unistd.h>
+#include <malloc.h>
#include <pthread.h>
-
-
-
#include <sched.h>
+#include <stdio.h>
+#include <string.h>
+#include <sysrepo/xpath.h>
+#include <unistd.h>
/* Hicn headers */
#include <hicn/util/ip_address.h>
+
#include "../hicn_plugin.h"
#include "../hicn_vpp_comm.h"
#include "hicn_model.h"
#include "tlock.h"
-
DEFINE_VAPI_MSG_IDS_HICN_API_JSON
-
// Shared local variables between state and RPCs
/**
* @brief this shared variable keeps the hicn state
*/
-volatile hicn_state_t * hicn_state = NULL;
+volatile hicn_state_t *hicn_state = NULL;
/**
* @brief this shared variable keeps hicn strategies
*/
-volatile hicn_strategies_t * hicn_strategies =NULL;
+volatile hicn_strategies_t *hicn_strategies = NULL;
/**
* @brief this shared variable keeps statistics of hicn faces
*/
-volatile hicn_faces_t * hicn_faces = NULL;
+volatile hicn_faces_t *hicn_faces = NULL;
/**
* @brief this shared variable keeps routes information in hicn
*/
-volatile hicn_routes_t * hicn_routes = NULL;
+volatile hicn_routes_t *hicn_routes = NULL;
/**
- * @brief this shared variable is the link list to maintain all the faces (up to MAX_FACES)
+ * @brief this shared variable is the link list to maintain all the faces (up to
+ * MAX_FACES)
*/
-struct hicn_faces_s * fcurrent = NULL;
+struct hicn_faces_s *fcurrent = NULL;
/**
* @brief this shared variable is the link list to maintain all the routes
*/
-struct hicn_routes_s * rcurrent = NULL;
-
-
-static int init_buffer(void){
-
- hicn_state = memalign(MEM_ALIGN, sizeof(hicn_state_t) );
- memset((hicn_state_t *)hicn_state, 0 , sizeof(hicn_state_t) );
+struct hicn_routes_s *rcurrent = NULL;
- hicn_strategies = memalign(MEM_ALIGN, sizeof(hicn_strategies_t) );
- memset((hicn_strategies_t *) hicn_strategies, 0 , sizeof(hicn_strategies_t) );
+static int init_buffer(void) {
+ hicn_state = memalign(MEM_ALIGN, sizeof(hicn_state_t));
+ memset((hicn_state_t *)hicn_state, 0, sizeof(hicn_state_t));
- hicn_faces = memalign(MEM_ALIGN, sizeof(hicn_faces_t) );
- hicn_faces->next=memalign(MEM_ALIGN, sizeof(struct hicn_faces_s));
- fcurrent=hicn_faces->next;
+ hicn_strategies = memalign(MEM_ALIGN, sizeof(hicn_strategies_t));
+ memset((hicn_strategies_t *)hicn_strategies, 0, sizeof(hicn_strategies_t));
+ hicn_faces = memalign(MEM_ALIGN, sizeof(hicn_faces_t));
+ hicn_faces->next = memalign(MEM_ALIGN, sizeof(struct hicn_faces_s));
+ fcurrent = hicn_faces->next;
- hicn_routes = memalign(MEM_ALIGN, sizeof(hicn_routes_t) );
- hicn_routes->next=memalign(MEM_ALIGN, sizeof(struct hicn_routes_s));
- rcurrent=hicn_routes->next;
+ hicn_routes = memalign(MEM_ALIGN, sizeof(hicn_routes_t));
+ hicn_routes->next = memalign(MEM_ALIGN, sizeof(struct hicn_routes_s));
+ rcurrent = hicn_routes->next;
+ int retval = -1;
+ ARG_CHECK5(retval, hicn_state, hicn_strategies, fcurrent, hicn_faces,
+ hicn_routes);
+ hicn_routes->nroute = 0;
+ hicn_faces->nface = 0;
+ retval = 0;
- int retval=-1;
- ARG_CHECK5(retval, hicn_state, hicn_strategies, fcurrent, hicn_faces, hicn_routes);
- hicn_routes->nroute=0;
- hicn_faces->nface=0;
- retval=0;
-
- return retval;
+ return retval;
}
-static int init_face_pool(struct hicn_faces_s * head){
-
- for(int i=0; i<MAX_FACE_POOL; i++){
- head->next=memalign(MEM_ALIGN, sizeof(struct hicn_faces_s));
- head=head->next;
- }
- SRP_LOG_DBGMSG("Face memory pool allocated\n");
- head->next=NULL;
- return 0;
-
+static int init_face_pool(struct hicn_faces_s *head) {
+ for (int i = 0; i < MAX_FACE_POOL; i++) {
+ head->next = memalign(MEM_ALIGN, sizeof(struct hicn_faces_s));
+ head = head->next;
+ }
+ SRP_LOG_DBGMSG("Face memory pool allocated\n");
+ head->next = NULL;
+ return 0;
}
-static int init_route_pool(struct hicn_routes_s * head){
-
- for(int i=0; i<MAX_ROUTE_POOL; i++){
- head->next=memalign(MEM_ALIGN, sizeof(struct hicn_routes_s));
- head=head->next;
- }
- SRP_LOG_DBGMSG("Route memory pool allocated\n");
- head->next=NULL;
- return 0;
-
+static int init_route_pool(struct hicn_routes_s *head) {
+ for (int i = 0; i < MAX_ROUTE_POOL; i++) {
+ head->next = memalign(MEM_ALIGN, sizeof(struct hicn_routes_s));
+ head = head->next;
+ }
+ SRP_LOG_DBGMSG("Route memory pool allocated\n");
+ head->next = NULL;
+ return 0;
}
/* VAPI CALLBACKS */
-static vapi_error_e call_hicn_api_strategies_get(struct vapi_ctx_s *ctx,
- void *callback_ctx,
- vapi_error_e rv,
- bool is_last,
- vapi_payload_hicn_api_strategies_get_reply *reply){
-if(!reply->retval){
- SRP_LOG_DBGMSG("Successfully done");
- return VAPI_OK;
- }else
- return VAPI_EUSER;
-}
-
-static vapi_error_e call_hicn_api_route_nhops_add(struct vapi_ctx_s *ctx,
- void *callback_ctx,
- vapi_error_e rv,
- bool is_last,
- vapi_payload_hicn_api_route_nhops_add_reply *reply){
-if(!reply->retval){
- SRP_LOG_DBGMSG("Successfully done");
- return VAPI_OK;
- }else
- return VAPI_EUSER;
-}
-
-static vapi_error_e call_hicn_api_route_del(struct vapi_ctx_s *ctx,
- void *callback_ctx,
- vapi_error_e rv,
- bool is_last,
- vapi_payload_hicn_api_route_del_reply *reply){
-
-if(!reply->retval){
- SRP_LOG_DBGMSG("Successfully done");
- return VAPI_OK;
- }else
- return VAPI_EUSER;
-}
-
-static vapi_error_e call_hicn_api_face_ip_params_get(struct vapi_ctx_s *ctx,
- void *callback_ctx,
- vapi_error_e rv,
- bool is_last,
- vapi_payload_hicn_api_face_ip_params_get_reply *reply){
-if(!reply->retval){
- if (callback_ctx!=NULL){
- struct hicn_faces_s * tmp;
- tmp = (struct hicn_faces_s *) callback_ctx;
+static vapi_error_e call_hicn_api_strategies_get(
+ struct vapi_ctx_s *ctx, void *callback_ctx, vapi_error_e rv, bool is_last,
+ vapi_payload_hicn_api_strategies_get_reply *reply) {
+ if (!reply->retval) {
+ SRP_LOG_DBGMSG("Successfully done");
+ return VAPI_OK;
+ } else
+ return VAPI_EUSER;
+}
+
+static vapi_error_e call_hicn_api_face_params_get(
+ struct vapi_ctx_s *ctx, void *callback_ctx, vapi_error_e rv, bool is_last,
+ vapi_payload_hicn_api_face_params_get_reply *reply) {
+ if (!reply->retval) {
+ if (callback_ctx != NULL) {
+ struct hicn_faces_s *tmp;
+ tmp = (struct hicn_faces_s *)callback_ctx;
tmp->face.intfc = reply->swif;
+ }
+ return VAPI_OK;
+ } else
+ return VAPI_EUSER;
+}
+
+static vapi_error_e call_vapi_hicn_api_node_stats_get(
+ struct vapi_ctx_s *ctx, void *callback_ctx, vapi_error_e rv, bool is_last,
+ vapi_payload_hicn_api_node_stats_get_reply *reply) {
+ if (!reply->retval) {
+ hicn_state->pkts_processed = reply->pkts_processed;
+ hicn_state->pkts_interest_count = reply->pkts_interest_count;
+ hicn_state->pkts_data_count = reply->pkts_data_count;
+ hicn_state->pkts_from_cache_count = reply->pkts_from_cache_count;
+ hicn_state->pkts_no_pit_count = reply->pkts_no_pit_count;
+ hicn_state->pit_expired_count = reply->pit_expired_count;
+ hicn_state->cs_expired_count = reply->cs_expired_count;
+ hicn_state->cs_lru_count = reply->cs_lru_count;
+ hicn_state->pkts_drop_no_buf = reply->pkts_drop_no_buf;
+ hicn_state->interests_aggregated = reply->interests_aggregated;
+ hicn_state->interests_retx = reply->interests_retx;
+ hicn_state->pit_entries_count = reply->pit_entries_count;
+ hicn_state->cs_entries_count = reply->cs_entries_count;
+ hicn_state->cs_entries_ntw_count = reply->cs_entries_ntw_count;
+ return VAPI_OK;
+ } else
+ return VAPI_EUSER;
+}
+
+static inline void state_update(sr_val_t *vals, struct lyd_node **parent,
+ sr_session_ctx_t *session) {
+ char buf[20];
+
+ sr_val_set_xpath(&vals[0], "/hicn:hicn-state/states/pkts_processed");
+ vals[0].type = SR_UINT64_T;
+ vals[0].data.uint64_val = hicn_state->pkts_processed;
+ memset(buf, 0x00, 20);
+ sprintf(buf, "%" PRIu64, hicn_state->pkts_processed);
+ *parent =
+ lyd_new_path(NULL, sr_get_context(sr_session_get_connection(session)),
+ vals[0].xpath, buf, 0, 0);
+
+ sr_val_set_xpath(&vals[1], "/hicn:hicn-state/states/pkts_interest_count");
+ vals[1].type = SR_UINT64_T;
+ vals[1].data.uint64_val = hicn_state->pkts_interest_count;
+ memset(buf, 0x00, 20);
+ sprintf(buf, "%" PRIu64, hicn_state->pkts_interest_count);
+ lyd_new_path(*parent, NULL, vals[1].xpath, buf, 0, 0);
+
+ sr_val_set_xpath(&vals[2], "/hicn:hicn-state/states/pkts_data_count");
+ vals[2].type = SR_UINT64_T;
+ vals[2].data.uint64_val = hicn_state->pkts_data_count;
+ memset(buf, 0x00, 20);
+ sprintf(buf, "%" PRIu64, hicn_state->pkts_data_count);
+ lyd_new_path(*parent, NULL, vals[2].xpath, buf, 0, 0);
+
+ sr_val_set_xpath(&vals[3], "/hicn:hicn-state/states/pkts_from_cache_count");
+ vals[3].type = SR_UINT64_T;
+ vals[3].data.uint64_val = hicn_state->pkts_from_cache_count;
+ memset(buf, 0x00, 20);
+ sprintf(buf, "%" PRIu64, hicn_state->pkts_from_cache_count);
+ lyd_new_path(*parent, NULL, vals[3].xpath, buf, 0, 0);
+
+ sr_val_set_xpath(&vals[4], "/hicn:hicn-state/states/pkts_no_pit_count");
+ vals[4].type = SR_UINT64_T;
+ vals[4].data.uint64_val = hicn_state->pkts_no_pit_count;
+ memset(buf, 0x00, 20);
+ sprintf(buf, "%" PRIu64, hicn_state->pkts_no_pit_count);
+ lyd_new_path(*parent, NULL, vals[4].xpath, buf, 0, 0);
+
+ sr_val_set_xpath(&vals[5], "/hicn:hicn-state/states/pit_expired_count");
+ vals[5].type = SR_UINT64_T;
+ vals[5].data.uint64_val = hicn_state->pit_expired_count;
+ memset(buf, 0x00, 20);
+ sprintf(buf, "%" PRIu64, hicn_state->pit_expired_count);
+ lyd_new_path(*parent, NULL, vals[5].xpath, buf, 0, 0);
+
+ sr_val_set_xpath(&vals[6], "/hicn:hicn-state/states/cs_expired_count");
+ vals[6].type = SR_UINT64_T;
+ vals[6].data.uint64_val = hicn_state->cs_expired_count;
+ memset(buf, 0x00, 20);
+ sprintf(buf, "%" PRIu64, hicn_state->cs_expired_count);
+ lyd_new_path(*parent, NULL, vals[6].xpath, buf, 0, 0);
+
+ sr_val_set_xpath(&vals[7], "/hicn:hicn-state/states/cs_lru_count");
+ vals[7].type = SR_UINT64_T;
+ vals[7].data.uint64_val = hicn_state->cs_lru_count;
+ memset(buf, 0x00, 20);
+ sprintf(buf, "%" PRIu64, hicn_state->cs_lru_count);
+ lyd_new_path(*parent, NULL, vals[7].xpath, buf, 0, 0);
+
+ sr_val_set_xpath(&vals[8], "/hicn:hicn-state/states/pkts_drop_no_buf");
+ vals[8].type = SR_UINT64_T;
+ vals[8].data.uint64_val = hicn_state->pkts_drop_no_buf;
+ memset(buf, 0x00, 20);
+ sprintf(buf, "%" PRIu64, hicn_state->pkts_drop_no_buf);
+ lyd_new_path(*parent, NULL, vals[8].xpath, buf, 0, 0);
+
+ sr_val_set_xpath(&vals[9], "/hicn:hicn-state/states/interests_aggregated");
+ vals[9].type = SR_UINT64_T;
+ vals[9].data.uint64_val = hicn_state->interests_aggregated;
+ memset(buf, 0x00, 20);
+ sprintf(buf, "%" PRIu64, hicn_state->interests_aggregated);
+ lyd_new_path(*parent, NULL, vals[9].xpath, buf, 0, 0);
+
+ sr_val_set_xpath(&vals[10], "/hicn:hicn-state/states/interests_retx");
+ vals[10].type = SR_UINT64_T;
+ vals[10].data.uint64_val = hicn_state->interests_retx;
+ memset(buf, 0x00, 20);
+ sprintf(buf, "%" PRIu64, hicn_state->interests_retx);
+ lyd_new_path(*parent, NULL, vals[10].xpath, buf, 0, 0);
+
+ sr_val_set_xpath(&vals[11],
+ "/hicn:hicn-state/states/interests_hash_collision");
+ vals[11].type = SR_UINT64_T;
+ vals[11].data.uint64_val = hicn_state->interests_hash_collision;
+ memset(buf, 0x00, 20);
+ sprintf(buf, "%" PRIu64, hicn_state->interests_hash_collision);
+ lyd_new_path(*parent, NULL, vals[11].xpath, buf, 0, 0);
+
+ sr_val_set_xpath(&vals[12], "/hicn:hicn-state/states/pit_entries_count");
+ vals[12].type = SR_UINT64_T;
+ vals[12].data.uint64_val = hicn_state->pit_entries_count;
+ memset(buf, 0x00, 20);
+ sprintf(buf, "%" PRIu64, hicn_state->pit_entries_count);
+ lyd_new_path(*parent, NULL, vals[12].xpath, buf, 0, 0);
+
+ sr_val_set_xpath(&vals[13], "/hicn:hicn-state/states/cs_entries_count");
+ vals[13].type = SR_UINT64_T;
+ vals[13].data.uint64_val = hicn_state->cs_entries_count;
+ memset(buf, 0x00, 20);
+ sprintf(buf, "%" PRIu64, hicn_state->cs_entries_count);
+ lyd_new_path(*parent, NULL, vals[13].xpath, buf, 0, 0);
+
+ sr_val_set_xpath(&vals[14], "/hicn:hicn-state/states/cs_entries_ntw_count");
+ vals[14].type = SR_UINT64_T;
+ vals[14].data.uint64_val = hicn_state->cs_entries_ntw_count;
+ memset(buf, 0x00, 20);
+ sprintf(buf, "%" PRIu64, hicn_state->cs_entries_ntw_count);
+ lyd_new_path(*parent, NULL, vals[14].xpath, buf, 0, 0);
+}
+
+static inline int routes_update(sr_val_t *vals, uint32_t nleaves,
+ struct lyd_node **parent,
+ sr_session_ctx_t *session) {
+ struct hicn_routes_s *temp = hicn_routes->next;
+ char buf[20];
+ int route = 0;
+ for (int count = 0; count < nleaves; count++) {
+ sr_val_build_xpath(&vals[route], "%s[routeid='%d']/prefix",
+ "/hicn:hicn-state/routes/route", temp->route.route_id);
+ vals[route].type = SR_STRING_T;
+
+ memset(buf, 0x00, 20);
+ if (temp->route.prefix.address.af == ADDRESS_IP4) {
+ struct sockaddr_in sa;
+ memcpy(&sa.sin_addr.s_addr, temp->route.prefix.address.un.ip4,
+ IPV4_ADDR_LEN);
+ inet_ntop(AF_INET, &(sa.sin_addr), buf, INET_ADDRSTRLEN);
+ vals[route].data.string_val = buf;
+ } else {
+ struct sockaddr_in6 sa;
+ memcpy(&sa.sin6_addr, temp->route.prefix.address.un.ip6, IPV6_ADDR_LEN);
+ inet_ntop(AF_INET6, &(sa.sin6_addr), buf, INET6_ADDRSTRLEN);
+ vals[route].data.string_val = buf;
+ }
+
+ lyd_new_path(*parent, NULL, vals[route].xpath, buf, 0, 0);
+
+ route++;
+
+ sr_val_build_xpath(&vals[route], "%s[routeid='%d']/strategy_id",
+ "/hicn:hicn-state/routes/route", temp->route.route_id);
+ vals[route].type = SR_UINT32_T;
+ vals[route].data.uint32_val = temp->route.strategy_id;
+ memset(buf, 0x00, 20);
+ sprintf(buf, "%d", temp->route.strategy_id);
+ lyd_new_path(*parent, NULL, vals[route].xpath, buf, 0, 0);
+
+ route++;
+
+ temp = temp->next;
}
- return VAPI_OK;
- }else
- return VAPI_EUSER;
-}
-static vapi_error_e call_hicn_api_route_nhop_del(struct vapi_ctx_s *ctx,
- void *callback_ctx,
- vapi_error_e rv,
- bool is_last,
- vapi_payload_hicn_api_route_nhop_del_reply *reply){
-if(!reply->retval){
- SRP_LOG_DBGMSG("Successfully done");
- return VAPI_OK;
- }else
- return VAPI_EUSER;
-}
-
-static vapi_error_e call_hicn_api_face_ip_del(struct vapi_ctx_s *ctx,
- void *callback_ctx,
- vapi_error_e rv,
- bool is_last,
- vapi_payload_hicn_api_face_ip_del_reply *reply){
-if(!reply->retval){
- SRP_LOG_DBGMSG("Successfully done");
- return VAPI_OK;
- }else
- return VAPI_EUSER;
-}
-
-
-static vapi_error_e call_hicn_api_face_ip_add(struct vapi_ctx_s *ctx,
- void *callback_ctx,
- vapi_error_e rv,
- bool is_last,
- vapi_payload_hicn_api_face_ip_add_reply *reply){
-if(!reply->retval){
- SRP_LOG_DBGMSG("Successfully done");
- return VAPI_OK;
- }else
- return VAPI_EUSER;
-
-}
-
-static vapi_error_e call_vapi_hicn_api_node_stats_get(struct vapi_ctx_s *ctx,
- void *callback_ctx,
- vapi_error_e rv,
- bool is_last,
- vapi_payload_hicn_api_node_stats_get_reply *reply){
-
-
-if(!reply->retval){
- hicn_state->pkts_processed = reply->pkts_processed;
- hicn_state->pkts_interest_count = reply->pkts_interest_count;
- hicn_state->pkts_data_count = reply->pkts_data_count;
- hicn_state->pkts_from_cache_count = reply->pkts_from_cache_count;
- hicn_state->pkts_no_pit_count = reply->pkts_no_pit_count;
- hicn_state->pit_expired_count = reply->pit_expired_count;
- hicn_state->cs_expired_count = reply->cs_expired_count;
- hicn_state->cs_lru_count = reply->cs_lru_count;
- hicn_state->pkts_drop_no_buf = reply->pkts_drop_no_buf;
- hicn_state->interests_aggregated = reply->interests_aggregated;
- hicn_state->interests_retx = reply->interests_retx;
- hicn_state->pit_entries_count = reply->pit_entries_count;
- hicn_state->cs_entries_count = reply->cs_entries_count;
- hicn_state->cs_entries_ntw_count = reply->cs_entries_ntw_count;
- return VAPI_OK;
- }else
- return VAPI_EUSER;
-}
+ SRP_LOG_DBGMSG("Routes state updated \n");
+ return SR_ERR_OK;
+}
+
+static inline int faces_update(sr_val_t *vals, uint32_t nleaves,
+ struct lyd_node **parent,
+ sr_session_ctx_t *session) {
+ struct hicn_faces_s *temp = hicn_faces->next;
+ char buf[20];
+ int face = 0;
+
+ for (int count = 0; count < nleaves; count++) {
+ vapi_msg_hicn_api_face_params_get *msg;
+ msg = vapi_alloc_hicn_api_face_params_get(g_vapi_ctx_instance);
+
+ msg->payload.faceid = temp->face.faceid;
+
+ if (vapi_hicn_api_face_params_get(g_vapi_ctx_instance, msg,
+ call_hicn_api_face_params_get,
+ (void *)temp) != VAPI_OK) {
+ SRP_LOG_DBGMSG("Operation failed");
+ return SR_ERR_OPERATION_FAILED;
+ }
+
+ sr_val_build_xpath(&vals[face], "%s[faceid='%d']/intfc",
+ "/hicn:hicn-state/faces/face", temp->face.faceid);
+ vals[face].type = SR_UINT32_T;
+ vals[face].data.uint32_val = temp->face.intfc;
+ memset(buf, 0x00, 20);
+ sprintf(buf, "%u", temp->face.intfc);
+ lyd_new_path(*parent, NULL, vals[face].xpath, buf, 0, 0);
+
+ face++;
+
+ sr_val_build_xpath(&vals[face], "%s[faceid='%d']/irx_packets",
+ "/hicn:hicn-state/faces/face", temp->face.faceid);
+ vals[face].type = SR_UINT64_T;
+ vals[face].data.uint64_val = temp->face.irx_packets;
+ memset(buf, 0x00, 20);
+ sprintf(buf, "%" PRIu64, temp->face.irx_packets);
+ lyd_new_path(*parent, NULL, vals[face].xpath, buf, 0, 0);
+
+ face++;
+
+ sr_val_build_xpath(&vals[face], "%s[faceid='%d']/irx_bytes",
+ "/hicn:hicn-state/faces/face", temp->face.faceid);
+ vals[face].type = SR_UINT64_T;
+ vals[face].data.uint64_val = temp->face.irx_bytes;
+ memset(buf, 0x00, 20);
+ sprintf(buf, "%" PRIu64, temp->face.irx_bytes);
+ lyd_new_path(*parent, NULL, vals[face].xpath, buf, 0, 0);
+
+ face++;
+
+ sr_val_build_xpath(&vals[face], "%s[faceid='%d']/itx_packets",
+ "/hicn:hicn-state/faces/face", temp->face.faceid);
+ vals[face].type = SR_UINT64_T;
+ vals[face].data.uint64_val = temp->face.itx_packets;
+ memset(buf, 0x00, 20);
+ sprintf(buf, "%" PRIu64, temp->face.itx_packets);
+ lyd_new_path(*parent, NULL, vals[face].xpath, buf, 0, 0);
+
+ face++;
+
+ sr_val_build_xpath(&vals[face], "%s[faceid='%d']/itx_bytes",
+ "/hicn:hicn-state/faces/face", temp->face.faceid);
+ vals[face].type = SR_UINT64_T;
+ vals[face].data.uint64_val = temp->face.itx_bytes;
+ memset(buf, 0x00, 20);
+ sprintf(buf, "%" PRIu64, temp->face.itx_bytes);
+ lyd_new_path(*parent, NULL, vals[face].xpath, buf, 0, 0);
+
+ face++;
+
+ sr_val_build_xpath(&vals[face], "%s[faceid='%d']/drx_packets",
+ "/hicn:hicn-state/faces/face", temp->face.faceid);
+ vals[face].type = SR_UINT64_T;
+ vals[face].data.uint64_val = temp->face.drx_packets;
+ memset(buf, 0x00, 20);
+ sprintf(buf, "%" PRIu64, temp->face.drx_packets);
+ lyd_new_path(*parent, NULL, vals[face].xpath, buf, 0, 0);
+
+ face++;
+
+ sr_val_build_xpath(&vals[face], "%s[faceid='%d']/drx_bytes",
+ "/hicn:hicn-state/faces/face", temp->face.faceid);
+ vals[face].type = SR_UINT64_T;
+ vals[face].data.uint64_val = temp->face.drx_bytes;
+ memset(buf, 0x00, 20);
+ sprintf(buf, "%" PRIu64, temp->face.drx_packets);
+ lyd_new_path(*parent, NULL, vals[face].xpath, buf, 0, 0);
+
+ face++;
+
+ sr_val_build_xpath(&vals[face], "%s[faceid='%d']/dtx_packets",
+ "/hicn:hicn-state/faces/face", temp->face.faceid);
+ vals[face].type = SR_UINT64_T;
+ vals[face].data.uint64_val = temp->face.dtx_packets;
+ memset(buf, 0x00, 20);
+ sprintf(buf, "%" PRIu64, temp->face.dtx_packets);
+ lyd_new_path(*parent, NULL, vals[face].xpath, buf, 0, 0);
+
+ face++;
+
+ sr_val_build_xpath(&vals[face], "%s[faceid='%d']/dtx_bytes",
+ "/hicn:hicn-state/faces/face", temp->face.faceid);
+ vals[face].type = SR_UINT64_T;
+ vals[face].data.uint64_val = temp->face.dtx_bytes;
+ memset(buf, 0x00, 20);
+ sprintf(buf, "%" PRIu64, temp->face.dtx_bytes);
+ lyd_new_path(*parent, NULL, vals[face].xpath, buf, 0, 0);
+
+ face++;
+
+ temp = temp->next;
+ }
+ SRP_LOG_DBGMSG("Faces state updated \n");
+ return SR_ERR_OK;
+}
+
+static int hicn_state_states_cb(sr_session_ctx_t *session,
+ const char *module_name, const char *path,
+ const char *request_xpath, uint32_t request_id,
+ struct lyd_node **parent, void *private_data) {
+ sr_val_t *vals;
+ int rc;
+ enum locks_name state;
+ state = lstate;
+ SRP_LOG_DBGMSG("Requesting state data");
+
+ rc = sr_new_values(NSTATE_LEAVES, &vals);
+ if (SR_ERR_OK != rc) {
+ return rc;
+ }
-static inline void state_update(sr_val_t * vals, struct lyd_node **parent, sr_session_ctx_t *session){
- char buf[20];
-
- sr_val_set_xpath(&vals[0], "/hicn:hicn-state/states/pkts_processed");
- vals[0].type = SR_UINT64_T;
- vals[0].data.uint64_val = hicn_state->pkts_processed;
- memset(buf, 0x00, 20);
- sprintf( buf, "%" PRIu64, hicn_state->pkts_processed);
- * parent = lyd_new_path(NULL, sr_get_context(sr_session_get_connection(session)), vals[0].xpath, buf, 0, 0);
-
- sr_val_set_xpath(&vals[1], "/hicn:hicn-state/states/pkts_interest_count");
- vals[1].type = SR_UINT64_T;
- vals[1].data.uint64_val = hicn_state->pkts_interest_count;
- memset(buf, 0x00, 20);
- sprintf( buf, "%" PRIu64, hicn_state->pkts_interest_count );
- lyd_new_path(*parent, NULL, vals[1].xpath, buf, 0, 0);
-
- sr_val_set_xpath(&vals[2], "/hicn:hicn-state/states/pkts_data_count");
- vals[2].type = SR_UINT64_T;
- vals[2].data.uint64_val = hicn_state->pkts_data_count;
- memset(buf, 0x00, 20);
- sprintf( buf, "%" PRIu64, hicn_state->pkts_data_count );
- lyd_new_path(*parent, NULL, vals[2].xpath, buf, 0, 0);
-
- sr_val_set_xpath(&vals[3], "/hicn:hicn-state/states/pkts_from_cache_count");
- vals[3].type = SR_UINT64_T;
- vals[3].data.uint64_val = hicn_state->pkts_from_cache_count;
- memset(buf, 0x00, 20);
- sprintf( buf, "%" PRIu64, hicn_state->pkts_from_cache_count );
- lyd_new_path(*parent, NULL, vals[3].xpath, buf, 0, 0);
-
- sr_val_set_xpath(&vals[4], "/hicn:hicn-state/states/pkts_no_pit_count");
- vals[4].type = SR_UINT64_T;
- vals[4].data.uint64_val = hicn_state->pkts_no_pit_count;
- memset(buf, 0x00, 20);
- sprintf( buf, "%" PRIu64, hicn_state->pkts_no_pit_count );
- lyd_new_path(*parent, NULL, vals[4].xpath, buf, 0, 0);
-
- sr_val_set_xpath(&vals[5], "/hicn:hicn-state/states/pit_expired_count");
- vals[5].type = SR_UINT64_T;
- vals[5].data.uint64_val = hicn_state->pit_expired_count;
- memset(buf, 0x00, 20);
- sprintf( buf, "%" PRIu64, hicn_state->pit_expired_count );
- lyd_new_path(*parent, NULL, vals[5].xpath, buf, 0, 0);
-
- sr_val_set_xpath(&vals[6], "/hicn:hicn-state/states/cs_expired_count");
- vals[6].type = SR_UINT64_T;
- vals[6].data.uint64_val = hicn_state->cs_expired_count;
- memset(buf, 0x00, 20);
- sprintf( buf, "%" PRIu64, hicn_state->cs_expired_count );
- lyd_new_path(*parent, NULL, vals[6].xpath, buf, 0, 0);
-
- sr_val_set_xpath(&vals[7], "/hicn:hicn-state/states/cs_lru_count");
- vals[7].type = SR_UINT64_T;
- vals[7].data.uint64_val = hicn_state->cs_lru_count;
- memset(buf, 0x00, 20);
- sprintf( buf, "%" PRIu64, hicn_state->cs_lru_count );
- lyd_new_path(*parent, NULL, vals[7].xpath, buf, 0, 0);
-
- sr_val_set_xpath(&vals[8], "/hicn:hicn-state/states/pkts_drop_no_buf");
- vals[8].type = SR_UINT64_T;
- vals[8].data.uint64_val = hicn_state->pkts_drop_no_buf;
- memset(buf, 0x00, 20);
- sprintf( buf, "%" PRIu64, hicn_state->pkts_drop_no_buf );
- lyd_new_path(*parent, NULL, vals[8].xpath, buf, 0, 0);
-
- sr_val_set_xpath(&vals[9], "/hicn:hicn-state/states/interests_aggregated");
- vals[9].type = SR_UINT64_T;
- vals[9].data.uint64_val = hicn_state->interests_aggregated;
- memset(buf, 0x00, 20);
- sprintf( buf, "%" PRIu64, hicn_state->interests_aggregated );
- lyd_new_path(*parent, NULL, vals[9].xpath, buf, 0, 0);
-
- sr_val_set_xpath(&vals[10], "/hicn:hicn-state/states/interests_retx");
- vals[10].type = SR_UINT64_T;
- vals[10].data.uint64_val = hicn_state->interests_retx;
- memset(buf, 0x00, 20);
- sprintf( buf, "%" PRIu64, hicn_state->interests_retx );
- lyd_new_path(*parent, NULL, vals[10].xpath, buf, 0, 0);
-
- sr_val_set_xpath(&vals[11],
- "/hicn:hicn-state/states/interests_hash_collision");
- vals[11].type = SR_UINT64_T;
- vals[11].data.uint64_val = hicn_state->interests_hash_collision;
- memset(buf, 0x00, 20);
- sprintf( buf, "%" PRIu64, hicn_state->interests_hash_collision );
- lyd_new_path(*parent, NULL, vals[11].xpath, buf, 0, 0);
-
- sr_val_set_xpath(&vals[12], "/hicn:hicn-state/states/pit_entries_count");
- vals[12].type = SR_UINT64_T;
- vals[12].data.uint64_val = hicn_state->pit_entries_count;
- memset(buf, 0x00, 20);
- sprintf( buf, "%" PRIu64, hicn_state->pit_entries_count );
- lyd_new_path(*parent, NULL, vals[12].xpath, buf, 0, 0);
-
- sr_val_set_xpath(&vals[13], "/hicn:hicn-state/states/cs_entries_count");
- vals[13].type = SR_UINT64_T;
- vals[13].data.uint64_val = hicn_state->cs_entries_count;
- memset(buf, 0x00, 20);
- sprintf( buf, "%" PRIu64, hicn_state->cs_entries_count );
- lyd_new_path(*parent, NULL, vals[13].xpath, buf, 0, 0);
-
- sr_val_set_xpath(&vals[14], "/hicn:hicn-state/states/cs_entries_ntw_count");
- vals[14].type = SR_UINT64_T;
- vals[14].data.uint64_val = hicn_state->cs_entries_ntw_count;
- memset(buf, 0x00, 20);
- sprintf( buf, "%" PRIu64, hicn_state->cs_entries_ntw_count );
- lyd_new_path(*parent, NULL, vals[14].xpath, buf, 0, 0);
+ tlock(state);
+ state_update(vals, parent, session);
+ tunlock(state);
+ return SR_ERR_OK;
}
-static inline int routes_update(sr_val_t * vals, uint32_t nleaves, struct lyd_node **parent, sr_session_ctx_t *session){
-
- struct hicn_routes_s * temp = hicn_routes->next;
- char buf[20];
- int route =0;
- for(int count=0; count<nleaves; count++){
-
- sr_val_build_xpath(&vals[route], "%s[routeid='%d']/prefix", "/hicn:hicn-state/routes/route",
- temp->route.route_id);
- vals[route].type = SR_STRING_T;
-
- memset(buf, 0x00, 20);
- if (temp->route.prefix.address.af==ADDRESS_IP4){
- struct sockaddr_in sa;
- memcpy(&sa.sin_addr.s_addr, temp->route.prefix.address.un.ip4, IPV4_ADDR_LEN);
- inet_ntop(AF_INET, &(sa.sin_addr), buf, INET_ADDRSTRLEN);
- vals[route].data.string_val = buf;
- }else{
- struct sockaddr_in6 sa;
- memcpy(&sa.sin6_addr,temp->route.prefix.address.un.ip6, IPV6_ADDR_LEN);
- inet_ntop(AF_INET6, &(sa.sin6_addr), buf, INET6_ADDRSTRLEN);
- vals[route].data.string_val = buf;
- }
-
-
- lyd_new_path(*parent, NULL, vals[route].xpath, buf, 0, 0);
-
-
- route++;
+static int hicn_state_route_cb(sr_session_ctx_t *session,
+ const char *module_name, const char *path,
+ const char *request_xpath, uint32_t request_id,
+ struct lyd_node **parent, void *private_data) {
+ sr_val_t *vals;
+ int rc;
+ enum locks_name route;
+ route = lroute;
+ uint32_t NROUTE_NODES = hicn_routes->nroute * ROUTES_CHILDREN;
- sr_val_build_xpath(&vals[route], "%s[routeid='%d']/strategy_id", "/hicn:hicn-state/routes/route",
- temp->route.route_id);
- vals[route].type = SR_UINT32_T;
- vals[route].data.uint32_val = temp->route.strategy_id;
- memset(buf, 0x00, 20);
- sprintf( buf, "%d", temp->route.strategy_id);
- lyd_new_path(*parent, NULL, vals[route].xpath, buf, 0, 0);
-
- route++;
-
- temp=temp->next;
+ rc = sr_new_values(NROUTE_NODES, &vals);
+ if (SR_ERR_OK != rc) {
+ return rc;
+ }
-}
+ tlock(route);
+ routes_update(vals, NROUTE_NODES / ROUTES_CHILDREN, parent, session);
+ tunlock(route);
- SRP_LOG_DBGMSG("Routes state updated \n");
- return SR_ERR_OK;
+ return SR_ERR_OK;
}
-static inline int faces_update(sr_val_t * vals, uint32_t nleaves, struct lyd_node **parent, sr_session_ctx_t *session){
-
- struct hicn_faces_s * temp = hicn_faces->next;
- char buf[20];
- int face =0;
-
-
- for(int count=0; count<nleaves; count++){
-
- vapi_msg_hicn_api_face_ip_params_get *msg;
- msg = vapi_alloc_hicn_api_face_ip_params_get(g_vapi_ctx_instance);
-
-
- msg->payload.faceid = temp->face.faceid;
-
- if(vapi_hicn_api_face_ip_params_get(g_vapi_ctx_instance,msg,call_hicn_api_face_ip_params_get, (void *)temp)!=VAPI_OK){
- SRP_LOG_DBGMSG("Operation failed");
- return SR_ERR_OPERATION_FAILED;
- }
-
- sr_val_build_xpath(&vals[face], "%s[faceid='%d']/intfc", "/hicn:hicn-state/faces/face",
- temp->face.faceid);
- vals[face].type = SR_UINT32_T;
- vals[face].data.uint32_val = temp->face.intfc;
- memset(buf, 0x00, 20);
- sprintf( buf,"%u", temp->face.intfc);
- lyd_new_path(*parent, NULL, vals[face].xpath, buf, 0, 0);
-
-
- face++;
-
-
- sr_val_build_xpath(&vals[face], "%s[faceid='%d']/irx_packets", "/hicn:hicn-state/faces/face",
- temp->face.faceid);
- vals[face].type = SR_UINT64_T;
- vals[face].data.uint64_val = temp->face.irx_packets;
- memset(buf, 0x00, 20);
- sprintf( buf, "%" PRIu64, temp->face.irx_packets);
- lyd_new_path(*parent, NULL, vals[face].xpath, buf, 0, 0);
-
- face++;
-
-
-
- sr_val_build_xpath(&vals[face], "%s[faceid='%d']/irx_bytes", "/hicn:hicn-state/faces/face",
- temp->face.faceid);
- vals[face].type = SR_UINT64_T;
- vals[face].data.uint64_val = temp->face.irx_bytes;
- memset(buf, 0x00, 20);
- sprintf( buf, "%" PRIu64, temp->face.irx_bytes);
- lyd_new_path(*parent, NULL, vals[face].xpath, buf, 0, 0);
-
- face++;
-
-
-
- sr_val_build_xpath(&vals[face], "%s[faceid='%d']/itx_packets", "/hicn:hicn-state/faces/face",
- temp->face.faceid);
- vals[face].type = SR_UINT64_T;
- vals[face].data.uint64_val = temp->face.itx_packets;
- memset(buf, 0x00, 20);
- sprintf( buf, "%" PRIu64, temp->face.itx_packets);
- lyd_new_path(*parent, NULL, vals[face].xpath, buf, 0, 0);
-
- face++;
-
-
+static int hicn_state_faces_cb(sr_session_ctx_t *session,
+ const char *module_name, const char *path,
+ const char *request_xpath, uint32_t request_id,
+ struct lyd_node **parent, void *private_data) {
+ sr_val_t *vals;
+ int rc;
+ enum locks_name faces;
+ faces = lfaces;
+ uint32_t NFACES_NODES = hicn_faces->nface * FACES_CHILDREN;
- sr_val_build_xpath(&vals[face], "%s[faceid='%d']/itx_bytes", "/hicn:hicn-state/faces/face",
- temp->face.faceid);
- vals[face].type = SR_UINT64_T;
- vals[face].data.uint64_val = temp->face.itx_bytes;
- memset(buf, 0x00, 20);
- sprintf( buf, "%" PRIu64, temp->face.itx_bytes);
- lyd_new_path(*parent, NULL, vals[face].xpath, buf, 0, 0);
-
-
- face++;
-
-
- sr_val_build_xpath(&vals[face], "%s[faceid='%d']/drx_packets", "/hicn:hicn-state/faces/face",
- temp->face.faceid);
- vals[face].type = SR_UINT64_T;
- vals[face].data.uint64_val = temp->face.drx_packets;
- memset(buf, 0x00, 20);
- sprintf( buf, "%" PRIu64, temp->face.drx_packets);
- lyd_new_path(*parent, NULL, vals[face].xpath, buf, 0, 0);
-
-
- face++;
-
-
-
- sr_val_build_xpath(&vals[face], "%s[faceid='%d']/drx_bytes", "/hicn:hicn-state/faces/face",
- temp->face.faceid);
- vals[face].type = SR_UINT64_T;
- vals[face].data.uint64_val = temp->face.drx_bytes;
- memset(buf, 0x00, 20);
- sprintf( buf, "%" PRIu64, temp->face.drx_packets);
- lyd_new_path(*parent, NULL, vals[face].xpath, buf, 0, 0);
-
-
- face++;
-
-
- sr_val_build_xpath(&vals[face], "%s[faceid='%d']/dtx_packets", "/hicn:hicn-state/faces/face",
- temp->face.faceid);
- vals[face].type = SR_UINT64_T;
- vals[face].data.uint64_val = temp->face.dtx_packets;
- memset(buf, 0x00, 20);
- sprintf( buf, "%" PRIu64, temp->face.dtx_packets);
- lyd_new_path(*parent, NULL, vals[face].xpath, buf, 0, 0);
-
- face++;
-
-
- sr_val_build_xpath(&vals[face], "%s[faceid='%d']/dtx_bytes", "/hicn:hicn-state/faces/face",
- temp->face.faceid);
- vals[face].type = SR_UINT64_T;
- vals[face].data.uint64_val = temp->face.dtx_bytes;
- memset(buf, 0x00, 20);
- sprintf( buf, "%" PRIu64, temp->face.dtx_bytes);
- lyd_new_path(*parent, NULL, vals[face].xpath, buf, 0, 0);
-
-
- face++;
+ rc = sr_new_values(NFACES_NODES, &vals);
+ if (SR_ERR_OK != rc) {
+ return rc;
+ }
- temp=temp->next;
+ tlock(faces);
+ faces_update(vals, NFACES_NODES / FACES_CHILDREN, parent, session);
+ tunlock(faces);
- }
- SRP_LOG_DBGMSG("Faces state updated \n");
- return SR_ERR_OK;
+ return SR_ERR_OK;
}
-static int hicn_state_states_cb(sr_session_ctx_t *session, const char *module_name, const char *path, const char *request_xpath,
- uint32_t request_id, struct lyd_node **parent, void *private_data) {
- sr_val_t *vals;
- int rc;
- enum locks_name state;
- state=lstate;
- SRP_LOG_DBGMSG("Requesting state data");
-
-
- rc = sr_new_values(NSTATE_LEAVES, &vals);
- if (SR_ERR_OK != rc) {
- return rc;
- }
+static int hicn_strategies_get_cb(sr_session_ctx_t *session, const char *path,
+ const sr_val_t *input, const size_t input_cnt,
+ sr_event_t event, uint32_t request_id,
+ sr_val_t **output, size_t *output_cnt,
+ void *private_data) {
+ SRP_LOG_DBGMSG("hicn strategies received successfully");
+ vapi_msg_hicn_api_strategies_get *msg;
+ msg = vapi_alloc_hicn_api_strategies_get(g_vapi_ctx_instance);
- tlock(state);
- state_update(vals,parent,session);
- tunlock(state);
-
-
- return SR_ERR_OK;
+ if (vapi_hicn_api_strategies_get(g_vapi_ctx_instance, msg,
+ call_hicn_api_strategies_get,
+ NULL) != VAPI_OK) {
+ SRP_LOG_DBGMSG("Operation failed");
+ return SR_ERR_OPERATION_FAILED;
+ }
+ return SR_ERR_OK;
}
-static int hicn_state_route_cb(sr_session_ctx_t *session, const char *module_name, const char *path, const char *request_xpath,
- uint32_t request_id, struct lyd_node **parent, void *private_data) {
- sr_val_t *vals;
- int rc;
- enum locks_name route;
- route=lroute;
- uint32_t NROUTE_NODES = hicn_routes->nroute * ROUTES_CHILDREN;
-
-
-
- rc = sr_new_values(NROUTE_NODES, &vals);
- if (SR_ERR_OK != rc) {
- return rc;
- }
+static int hicn_face_params_get_cb(sr_session_ctx_t *session, const char *path,
+ const sr_val_t *input,
+ const size_t input_cnt, sr_event_t event,
+ uint32_t request_id, sr_val_t **output,
+ size_t *output_cnt, void *private_data) {
+ SRP_LOG_DBGMSG("hicn face ip params get received successfully");
+ vapi_msg_hicn_api_face_params_get *msg;
- tlock(route);
- routes_update(vals,NROUTE_NODES/ROUTES_CHILDREN, parent, session);
- tunlock(route);
+ msg = vapi_alloc_hicn_api_face_params_get(g_vapi_ctx_instance);
+ msg->payload.faceid = input[0].data.uint32_val;
- return SR_ERR_OK;
-
- }
-
-
- static int hicn_state_faces_cb(sr_session_ctx_t *session, const char *module_name, const char *path, const char *request_xpath,
- uint32_t request_id, struct lyd_node **parent, void *private_data) {
-
-
- sr_val_t *vals;
- int rc;
- enum locks_name faces;
- faces=lfaces;
- uint32_t NFACES_NODES = hicn_faces->nface * FACES_CHILDREN;
-
- rc = sr_new_values(NFACES_NODES, &vals);
- if (SR_ERR_OK != rc) {
- return rc;
- }
-
- tlock(faces);
- faces_update(vals, NFACES_NODES/FACES_CHILDREN, parent, session);
- tunlock(faces);
-
- return SR_ERR_OK;
-
- }
-
-static int hicn_strategies_get_cb(sr_session_ctx_t *session, const char *path, const sr_val_t *input, const size_t input_cnt,
- sr_event_t event, uint32_t request_id, sr_val_t **output, size_t *output_cnt, void *private_data) {
-
-SRP_LOG_DBGMSG("hicn strategies received successfully");
-vapi_msg_hicn_api_strategies_get *msg;
-
-msg = vapi_alloc_hicn_api_strategies_get(g_vapi_ctx_instance);
-
-if (vapi_hicn_api_strategies_get(g_vapi_ctx_instance, msg, call_hicn_api_strategies_get, NULL)!=VAPI_OK){
- SRP_LOG_DBGMSG("Operation failed");
- return SR_ERR_OPERATION_FAILED;
-}
-return SR_ERR_OK;
+ if (vapi_hicn_api_face_params_get(g_vapi_ctx_instance, msg,
+ call_hicn_api_face_params_get,
+ NULL) != VAPI_OK) {
+ SRP_LOG_DBGMSG("Operation failed");
+ return SR_ERR_OPERATION_FAILED;
+ }
+ return SR_ERR_OK;
}
-static int hicn_route_nhops_add_cb(sr_session_ctx_t *session, const char *path, const sr_val_t *input, const size_t input_cnt,
- sr_event_t event, uint32_t request_id, sr_val_t **output, size_t *output_cnt, void *private_data) {
-
- SRP_LOG_DBGMSG("hicn route nhops add received successfully");
- vapi_msg_hicn_api_route_nhops_add *msg;
-
- msg = vapi_alloc_hicn_api_route_nhops_add(g_vapi_ctx_instance);
-
- if(strcmp(input[0].data.string_val,"-1")){
-
- struct sockaddr_in sa;
- inet_pton(AF_INET, input[0].data.string_val, &(sa.sin_addr));
- unsigned char * tmp = (unsigned char *) &sa.sin_addr.s_addr;
- memcpy(&msg->payload.prefix.address.un.ip4[0],tmp,B32);
- msg->payload.prefix.address.af = ADDRESS_IP4;
-
- }else if(strcmp(input[1].data.string_val,"-1")){
-
- void *dst = malloc(sizeof(struct in6_addr));
- inet_pton(AF_INET6, input[1].data.string_val, dst);
- unsigned char * tmp = (unsigned char *) ((struct in6_addr *)dst)->s6_addr;
- memcpy(&msg->payload.prefix.address.un.ip6[0],tmp,B128);
- msg->payload.prefix.address.af = ADDRESS_IP6;
-
- }else{
- SRP_LOG_DBGMSG("Invalid local IP address");
- return SR_ERR_OPERATION_FAILED;
- }
-
- msg->payload.prefix.len = input[2].data.uint8_val;
- msg->payload.face_ids[0] = input[3].data.uint32_val;
- msg->payload.face_ids[1] = input[4].data.uint32_val;
- msg->payload.face_ids[2] = input[5].data.uint32_val;
- msg->payload.face_ids[3] = input[6].data.uint32_val;
- msg->payload.face_ids[4] = input[7].data.uint32_val;
- msg->payload.face_ids[5] = input[8].data.uint32_val;
- msg->payload.face_ids[6] = input[9].data.uint32_val;
- msg->payload.n_faces = input[10].data.uint8_val;
-
-
-if(vapi_hicn_api_route_nhops_add(g_vapi_ctx_instance,msg,call_hicn_api_route_nhops_add,NULL)!=VAPI_OK){
- SRP_LOG_DBGMSG("Operation failed");
- return SR_ERR_OPERATION_FAILED;
+static vapi_error_e call_hicn_api_enable_disable(
+ struct vapi_ctx_s *ctx, void *callback_ctx, vapi_error_e rv, bool is_last,
+ vapi_payload_hicn_api_enable_disable_reply *reply) {
+ if (!reply->retval) {
+ SRP_LOG_DBGMSG("Successfully done");
+ return VAPI_OK;
+ } else
+ return VAPI_EUSER;
}
-return SR_ERR_OK;
-}
-
-static int hicn_route_del_cb(sr_session_ctx_t *session, const char *path, const sr_val_t *input, const size_t input_cnt,
- sr_event_t event, uint32_t request_id, sr_val_t **output, size_t *output_cnt, void *private_data) {
-
- SRP_LOG_DBGMSG("hicn route del received successfully");
- vapi_msg_hicn_api_route_del *msg;
- msg = vapi_alloc_hicn_api_route_del(g_vapi_ctx_instance);
+static int hicn_enable_cb(sr_session_ctx_t *session, const char *path,
+ const sr_val_t *input, const size_t input_cnt,
+ sr_event_t event, uint32_t request_id,
+ sr_val_t **output, size_t *output_cnt,
+ void *private_data) {
+ SRP_LOG_DBGMSG("hicn enable received successfully");
+ vapi_msg_hicn_api_enable_disable *msg;
- if(strcmp(input[0].data.string_val,"-1")){
+ msg = vapi_alloc_hicn_api_enable_disable(g_vapi_ctx_instance);
- struct sockaddr_in sa;
- inet_pton(AF_INET, input[0].data.string_val, &(sa.sin_addr));
- unsigned char * tmp = (unsigned char *) &sa.sin_addr.s_addr;
- memcpy(&msg->payload.prefix.address.un.ip4[0],tmp,B32);
- msg->payload.prefix.address.af = ADDRESS_IP4;
-
-
- }else if(strcmp(input[1].data.string_val,"-1")){
-
- void *dst = malloc(sizeof(struct in6_addr));
- inet_pton(AF_INET6, input[1].data.string_val, dst);
- unsigned char * tmp = (unsigned char *) ((struct in6_addr *)dst)->s6_addr;
- memcpy(&msg->payload.prefix.address.un.ip6[0],tmp,B128);
- msg->payload.prefix.address.af = ADDRESS_IP6;
-
- }else{
- SRP_LOG_DBGMSG("Invalid local IP address");
- return SR_ERR_OPERATION_FAILED;
- }
+ const char *delim = "/";
+ if (input->type != SR_STRING_T) {
+ SRP_LOG_DBGMSG("Expected prefix of type string");
+ return SR_ERR_OPERATION_FAILED;
+ }
+ char *token;
+
+ /* get the first token */
+ token = strtok(input->data.string_val, delim);
+
+ /* if null the address is ipv4 else ipv6*/
+ if (strrchr(token, ':') == NULL) {
+ struct sockaddr_in sa;
+ inet_pton(AF_INET, token, &(sa.sin_addr));
+ unsigned char *tmp = (unsigned char *)&sa.sin_addr.s_addr;
+ memcpy(&msg->payload.prefix.address.un.ip4[0], tmp, B32);
+ msg->payload.prefix.address.af = ADDRESS_IP4;
+ } else {
+ void *dst = malloc(sizeof(struct in6_addr));
+ inet_pton(AF_INET6, token, dst);
+ unsigned char *tmp = (unsigned char *)((struct in6_addr *)dst)->s6_addr;
+ memcpy(&msg->payload.prefix.address.un.ip6[0], tmp, B128);
+ msg->payload.prefix.address.af = ADDRESS_IP6;
+ }
+ /* The second token is the prefix len*/
+ token = strtok(NULL, delim);
- msg->payload.prefix.len = input[2].data.uint8_val;
+ msg->payload.prefix.len = atoi(token);
+ msg->payload.enable_disable = 1;
+ if (vapi_hicn_api_enable_disable(g_vapi_ctx_instance, msg,
+ call_hicn_api_enable_disable,
+ NULL) != VAPI_OK) {
+ SRP_LOG_DBGMSG("Operation failed");
+ return SR_ERR_OPERATION_FAILED;
+ }
-if(vapi_hicn_api_route_del(g_vapi_ctx_instance,msg,call_hicn_api_route_del,NULL)!=VAPI_OK){
- SRP_LOG_DBGMSG("Operation failed");
- return SR_ERR_OPERATION_FAILED;
+ return SR_ERR_OK;
}
-return SR_ERR_OK;
-}
-
-static int hicn_face_ip_params_get_cb(sr_session_ctx_t *session, const char *path, const sr_val_t *input, const size_t input_cnt,
- sr_event_t event, uint32_t request_id, sr_val_t **output, size_t *output_cnt, void *private_data) {
-
- SRP_LOG_DBGMSG("hicn face ip params get received successfully");
- vapi_msg_hicn_api_face_ip_params_get *msg;
-
- msg = vapi_alloc_hicn_api_face_ip_params_get(g_vapi_ctx_instance);
- msg->payload.faceid = input[0].data.uint32_val;
-
-if (vapi_hicn_api_face_ip_params_get(g_vapi_ctx_instance,msg,call_hicn_api_face_ip_params_get,NULL)!=VAPI_OK){
- SRP_LOG_DBGMSG("Operation failed");
- return SR_ERR_OPERATION_FAILED;
-}
-return SR_ERR_OK;
-}
+static int hicn_disable_cb(sr_session_ctx_t *session, const char *path,
+ const sr_val_t *input, const size_t input_cnt,
+ sr_event_t event, uint32_t request_id,
+ sr_val_t **output, size_t *output_cnt,
+ void *private_data) {
+ SRP_LOG_DBGMSG("hicn disable received successfully");
+ vapi_msg_hicn_api_enable_disable *msg;
-static int hicn_route_nhops_del_cb(sr_session_ctx_t *session, const char *path, const sr_val_t *input, const size_t input_cnt,
- sr_event_t event, uint32_t request_id, sr_val_t **output, size_t *output_cnt, void *private_data) {
+ msg = vapi_alloc_hicn_api_enable_disable(g_vapi_ctx_instance);
- SRP_LOG_DBGMSG("hicn route nhop del received successfully");
- // allocate memory msg
- vapi_msg_hicn_api_route_nhop_del *msg;
-
- msg = vapi_alloc_hicn_api_route_nhop_del(g_vapi_ctx_instance);
-
-
- if(strcmp(input[0].data.string_val,"-1")){
-
- struct sockaddr_in sa;
- // store this IP address in sa:
- inet_pton(AF_INET, input[0].data.string_val, &(sa.sin_addr));
- unsigned char * tmp = (unsigned char *) &sa.sin_addr.s_addr;
- memcpy(&msg->payload.prefix.address.un.ip4[0],tmp,B32);
- msg->payload.prefix.address.af = ADDRESS_IP4;
-
-
- }else if(strcmp(input[1].data.string_val,"-1")){
-
- void *dst = malloc(sizeof(struct in6_addr));
- inet_pton(AF_INET6, input[1].data.string_val, dst);
- unsigned char * tmp = (unsigned char *) ((struct in6_addr *)dst)->s6_addr;
- memcpy(&msg->payload.prefix.address.un.ip6[0],tmp,B128);
- msg->payload.prefix.address.af = ADDRESS_IP6;
-
- }else{
- SRP_LOG_DBGMSG("Invalid local IP address");
- return SR_ERR_OPERATION_FAILED;
- }
-
-
- msg->payload.prefix.len = input[2].data.uint8_val;
- msg->payload.faceid = input[3].data.uint32_val;
-
-
-if (vapi_hicn_api_route_nhop_del(g_vapi_ctx_instance, msg, call_hicn_api_route_nhop_del,NULL)!=VAPI_OK){
- SRP_LOG_DBGMSG("Operation failed");
- return SR_ERR_OPERATION_FAILED;
-}
-return SR_ERR_OK;
-}
-
-static int hicn_face_ip_del_cb(sr_session_ctx_t *session, const char *path, const sr_val_t *input, const size_t input_cnt,
- sr_event_t event, uint32_t request_id, sr_val_t **output, size_t *output_cnt, void *private_data) {
+ const char *delim = "/";
+ if (input->type != SR_STRING_T) {
+ SRP_LOG_DBGMSG("Expected prefix of type string");
+ return SR_ERR_OPERATION_FAILED;
+ }
+ char *token;
+
+ /* get the first token */
+ token = strtok(input->data.string_val, delim);
+
+ /* if null the address is ipv4 else ipv6*/
+ if (strrchr(token, ':') == NULL) {
+ struct sockaddr_in sa;
+ inet_pton(AF_INET, token, &(sa.sin_addr));
+ unsigned char *tmp = (unsigned char *)&sa.sin_addr.s_addr;
+ memcpy(&msg->payload.prefix.address.un.ip4[0], tmp, B32);
+ msg->payload.prefix.address.af = ADDRESS_IP4;
+ } else {
+ void *dst = malloc(sizeof(struct in6_addr));
+ inet_pton(AF_INET6, token, dst);
+ unsigned char *tmp = (unsigned char *)((struct in6_addr *)dst)->s6_addr;
+ memcpy(&msg->payload.prefix.address.un.ip6[0], tmp, B128);
+ msg->payload.prefix.address.af = ADDRESS_IP6;
+ }
- SRP_LOG_DBGMSG("hicn face ip del received successfully");
- // allocate memory msg
- vapi_msg_hicn_api_face_ip_del *msg;
+ /* The second token is the prefix len*/
+ token = strtok(NULL, delim);
- msg = vapi_alloc_hicn_api_face_ip_del(g_vapi_ctx_instance);
- msg->payload.faceid = input[0].data.uint32_val;
+ msg->payload.prefix.len = atoi(token);
+ msg->payload.enable_disable = 0;
+ if (vapi_hicn_api_enable_disable(g_vapi_ctx_instance, msg,
+ call_hicn_api_enable_disable,
+ NULL) != VAPI_OK) {
+ SRP_LOG_DBGMSG("Operation failed");
+ return SR_ERR_OPERATION_FAILED;
+ }
-if(vapi_hicn_api_face_ip_del(g_vapi_ctx_instance,msg, call_hicn_api_face_ip_del,NULL)!=VAPI_OK){
- SRP_LOG_DBGMSG("Operation failed");
- return SR_ERR_OPERATION_FAILED;
-}
-return SR_ERR_OK;
+ return SR_ERR_OK;
}
+static vapi_error_e hicn_api_routes_dump_cb(
+ struct vapi_ctx_s *ctx, void *callback_ctx, vapi_error_e rv, bool is_last,
+ vapi_payload_hicn_api_routes_details *reply) {
+ static int counter = 0;
-static int hicn_face_ip_add_cb(sr_session_ctx_t *session, const char *path, const sr_val_t *input, const size_t input_cnt,
- sr_event_t event, uint32_t request_id, sr_val_t **output, size_t *output_cnt, void *private_data) {
-
- SRP_LOG_DBGMSG("hicn face ip add received successfully");
-
-
- vapi_msg_hicn_api_face_ip_add *msg;
-
- msg = vapi_alloc_hicn_api_face_ip_add(g_vapi_ctx_instance);
- if(strcmp(input[0].data.string_val,"-1")){
- struct sockaddr_in sa;
- inet_pton(AF_INET, input[0].data.string_val, &(sa.sin_addr));
- unsigned char * tmp = (unsigned char *) &sa.sin_addr.s_addr;
- memcpy(&msg->payload.face.local_addr.un.ip4[0],tmp,B32);
- msg->payload.face.local_addr.af = ADDRESS_IP4;
-
- }else if(strcmp(input[1].data.string_val,"-1")){
-
- void *dst = malloc(sizeof(struct in6_addr));
- inet_pton(AF_INET6, input[1].data.string_val, dst);
- unsigned char * tmp = (unsigned char *) ((struct in6_addr *)dst)->s6_addr;
- memcpy(&msg->payload.face.local_addr.un.ip6[0],tmp,B128);
- msg->payload.face.local_addr.af = ADDRESS_IP6;
-
- }else{
- SRP_LOG_DBGMSG("Invalid local IP address");
- return SR_ERR_OPERATION_FAILED;
- }
-
- if(strcmp(input[2].data.string_val,"-1")){
+ tlock(lroute);
+ if (reply != NULL) {
+ rcurrent->route.route_id = counter;
+ rcurrent->route.prefix = reply->prefix;
+ rcurrent->route.nfaces = reply->nfaces;
+ rcurrent->route.strategy_id = reply->strategy_id;
+ for (int cnt = 0; cnt < rcurrent->route.nfaces; cnt++)
+ rcurrent->route.faceids[cnt] = rcurrent->route.faceids[cnt];
- struct sockaddr_in sa;
- inet_pton(AF_INET, input[2].data.string_val, &(sa.sin_addr));
- unsigned char * tmp = (unsigned char *)&sa.sin_addr.s_addr;
- memcpy(&msg->payload.face.remote_addr.un.ip4[0],tmp,B32);
- msg->payload.face.remote_addr.af = ADDRESS_IP4;
+ counter++;
+ rcurrent = rcurrent->next;
+ SRP_LOG_DBG("nfaces %d", reply->nfaces);
+ SRP_LOG_DBG("strategy_id %d", reply->strategy_id);
- }else if(strcmp(input[3].data.string_val,"-1")){
-
- void *dst = malloc(sizeof(struct in6_addr));
- inet_pton(AF_INET6, input[3].data.string_val, dst);
- unsigned char * tmp =(unsigned char *) ((struct in6_addr *)dst)->s6_addr;
- memcpy(&msg->payload.face.remote_addr.un.ip6[0],tmp,B128);
- msg->payload.face.remote_addr.af = ADDRESS_IP6;
-
- }else{
- SRP_LOG_DBGMSG("Invalid local IP address");
- return SR_ERR_OPERATION_FAILED;
- }
-
- msg->payload.face.swif = input[4].data.uint32_val; // This is the idx number of interface
-
-
-if(vapi_hicn_api_face_ip_add(g_vapi_ctx_instance,msg,call_hicn_api_face_ip_add,NULL)!=VAPI_OK){
- SRP_LOG_DBGMSG("Operation failed");
- return SR_ERR_OPERATION_FAILED;
-}
-return SR_ERR_OK;
-}
-
-static vapi_error_e
-hicn_api_routes_dump_cb(struct vapi_ctx_s *ctx, void *callback_ctx,
- vapi_error_e rv, bool is_last,
- vapi_payload_hicn_api_routes_details *reply)
-{
-
- static int counter = 0;
-
- tlock(lroute);
- if (reply!=NULL){
- rcurrent->route.route_id = counter;
- rcurrent->route.prefix = reply->prefix;
- rcurrent->route.nfaces = reply->nfaces;
- rcurrent->route.strategy_id = reply->strategy_id;
- for(int cnt=0;cnt<rcurrent->route.nfaces;cnt++)
- rcurrent->route.faceids[cnt] = rcurrent->route.faceids[cnt];
-
- counter++;
- rcurrent = rcurrent->next;
-
- SRP_LOG_DBG("nfaces %d", reply->nfaces);
- SRP_LOG_DBG("strategy_id %d", reply->strategy_id);
-
- }else
- {
- SRP_LOG_DBGMSG("---------Routes------- \n");
- hicn_routes->nroute=counter;
- counter=0;
- rcurrent=hicn_routes->next;
- }
- tunlock(lroute);
- return SR_ERR_OK;
-
-}
-
-
-static vapi_error_e
-hicn_api_face_stats_dump_cb(struct vapi_ctx_s *ctx, void *callback_ctx,
- vapi_error_e rv, bool is_last,
- vapi_payload_hicn_api_face_stats_details *reply)
-{
-
- static int counter = 0;
-
- tlock(lfaces);
- if (reply!=NULL){
-
- fcurrent->face.faceid = reply->faceid;
- fcurrent->face.intfc = 1;
- fcurrent->face.irx_packets = reply->irx_packets;
- fcurrent->face.irx_bytes = reply->irx_bytes;
- fcurrent->face.itx_packets = reply->itx_packets;
- fcurrent->face.itx_bytes = reply->itx_bytes;
- fcurrent->face.drx_packets = reply->drx_packets;
- fcurrent->face.drx_bytes = reply->drx_bytes;
- fcurrent->face.dtx_packets = reply->dtx_packets;
- fcurrent->face.dtx_bytes = reply->dtx_bytes;
- counter++;
- fcurrent = fcurrent->next;
- SRP_LOG_DBG("faceid %d", reply->faceid);
- SRP_LOG_DBG("drxB %d", reply->drx_bytes);
- SRP_LOG_DBG("dtxB %d", reply->dtx_bytes);
-
- }else
- {
- SRP_LOG_DBGMSG("---------Faces------- \n");
- hicn_faces->nface=counter;
- counter=0;
- fcurrent=hicn_faces->next;
- }
- tunlock(lfaces);
- return SR_ERR_OK;
+ } else {
+ SRP_LOG_DBGMSG("---------Routes------- \n");
+ hicn_routes->nroute = counter;
+ counter = 0;
+ rcurrent = hicn_routes->next;
+ }
+ tunlock(lroute);
+ return SR_ERR_OK;
+}
+
+static vapi_error_e hicn_api_face_stats_dump_cb(
+ struct vapi_ctx_s *ctx, void *callback_ctx, vapi_error_e rv, bool is_last,
+ vapi_payload_hicn_api_face_stats_details *reply) {
+ static int counter = 0;
+
+ tlock(lfaces);
+ if (reply != NULL) {
+ fcurrent->face.faceid = reply->faceid;
+ fcurrent->face.intfc = 1;
+ fcurrent->face.irx_packets = reply->irx_packets;
+ fcurrent->face.irx_bytes = reply->irx_bytes;
+ fcurrent->face.itx_packets = reply->itx_packets;
+ fcurrent->face.itx_bytes = reply->itx_bytes;
+ fcurrent->face.drx_packets = reply->drx_packets;
+ fcurrent->face.drx_bytes = reply->drx_bytes;
+ fcurrent->face.dtx_packets = reply->dtx_packets;
+ fcurrent->face.dtx_bytes = reply->dtx_bytes;
+ counter++;
+ fcurrent = fcurrent->next;
+ SRP_LOG_DBG("faceid %d", reply->faceid);
+ SRP_LOG_DBG("drxB %d", reply->drx_bytes);
+ SRP_LOG_DBG("dtxB %d", reply->dtx_bytes);
+
+ } else {
+ SRP_LOG_DBGMSG("---------Faces------- \n");
+ hicn_faces->nface = counter;
+ counter = 0;
+ fcurrent = hicn_faces->next;
+ }
+ tunlock(lfaces);
+ return SR_ERR_OK;
}
-
static void *state_thread(void *arg) {
+ // mapping can be retrieved by cpuinfo
+ int map = 0;
+ cpu_set_t cpuset;
+ CPU_ZERO(&cpuset);
+ CPU_SET(map, &cpuset);
+
+ // pin the thread to a core
+ if (pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset)) {
+ SRP_LOG_DBGMSG("Thread pining failed\n");
+ exit(1);
+ }
- // mapping can be retrieved by cpuinfo
- int map = 0;
- cpu_set_t cpuset;
- CPU_ZERO(&cpuset);
- CPU_SET(map, &cpuset);
-
- // pin the thread to a core
- if (pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset))
- {
- SRP_LOG_DBGMSG("Thread pining failed\n");
- exit(1);
- }
-
- vapi_msg_hicn_api_node_stats_get *msg=NULL;
- enum locks_name state;
- state=lstate;
-
- while(true){
-
- // dump faces
- vapi_msg_hicn_api_face_stats_dump *fmsg;
- fmsg = vapi_alloc_hicn_api_face_stats_dump(g_vapi_ctx_instance);
- vapi_hicn_api_face_stats_dump(g_vapi_ctx_instance, fmsg, hicn_api_face_stats_dump_cb, fcurrent);
-
- // dump routes
- vapi_msg_hicn_api_routes_dump *rmsg;
- rmsg = vapi_alloc_hicn_api_routes_dump(g_vapi_ctx_instance);
- vapi_hicn_api_routes_dump(g_vapi_ctx_instance, rmsg, hicn_api_routes_dump_cb, rcurrent);
+ vapi_msg_hicn_api_node_stats_get *msg = NULL;
+ enum locks_name state;
+ state = lstate;
+ while (true) {
+ tlock(state);
+ // dump faces
+ vapi_msg_hicn_api_face_stats_dump *fmsg;
+ fmsg = vapi_alloc_hicn_api_face_stats_dump(g_vapi_ctx_instance);
+ vapi_hicn_api_face_stats_dump(g_vapi_ctx_instance, fmsg,
+ hicn_api_face_stats_dump_cb, fcurrent);
+ // dump routes
+ vapi_msg_hicn_api_routes_dump *rmsg;
+ rmsg = vapi_alloc_hicn_api_routes_dump(g_vapi_ctx_instance);
+ vapi_hicn_api_routes_dump(g_vapi_ctx_instance, rmsg,
+ hicn_api_routes_dump_cb, rcurrent);
- msg = vapi_alloc_hicn_api_node_stats_get(g_vapi_ctx_instance);
+ msg = vapi_alloc_hicn_api_node_stats_get(g_vapi_ctx_instance);
+ if (vapi_hicn_api_node_stats_get(g_vapi_ctx_instance, msg,
+ call_vapi_hicn_api_node_stats_get,
+ NULL) != VAPI_OK) {
+ SRP_LOG_DBGMSG(" State operation failed");
+ }
- tlock(state);
+ tunlock(state);
+ sleep(1);
- if(vapi_hicn_api_node_stats_get(g_vapi_ctx_instance,msg,call_vapi_hicn_api_node_stats_get,NULL)!=VAPI_OK){
- SRP_LOG_DBGMSG(" State operation failed");
+ SRP_LOG_DBGMSG("state cached");
}
+ return NULL;
+}
+int hicn_subscribe_events(sr_session_ctx_t *session,
+ sr_subscription_ctx_t **subscription) {
+ int rc = SR_ERR_OK;
+ SRP_LOG_DBGMSG("Subscriging hicn.");
+
+ // Initializing the locks
+ for (int i = 0; i < NLOCKS; i++) ticket_init(i, LOCK_INIT);
+
+ // Initializing the buffer
+ rc = init_buffer();
+ if (rc != SR_ERR_OK) {
+ SRP_LOG_DBGMSG("Problem in initializing the buffers\n");
+ goto error;
+ }
- tunlock(state);
- sleep(1);
-
- SRP_LOG_DBGMSG("state cached");
+ SRP_LOG_DBGMSG("buffer initialized successfully.");
- }
- return NULL;
-}
+ rc = init_face_pool(fcurrent);
+ if (rc) {
+ SRP_LOG_DBGMSG("Problem in initializing the pools\n");
+ goto error;
+ }
+ rc = init_route_pool(rcurrent);
+ if (rc) {
+ SRP_LOG_DBGMSG("Problem in initializing the pools\n");
+ goto error;
+ }
-int hicn_subscribe_events(sr_session_ctx_t *session,
- sr_subscription_ctx_t **subscription) {
- int rc = SR_ERR_OK;
- SRP_LOG_DBGMSG("Subscriging hicn.");
+ SRP_LOG_DBGMSG("pools created successfully.");
- //Initializing the locks
- for (int i=0; i<NLOCKS; i++)
- ticket_init(i,LOCK_INIT);
+ // Create state thread observation
+ pthread_t state_tid;
+ rc = pthread_create((pthread_t *)&state_tid, NULL, state_thread, NULL);
+ if (rc != 0) {
+ SRP_LOG_DBGMSG("Error making hicn state thread");
+ return SR_ERR_OPERATION_FAILED;
+ }
+ SRP_LOG_DBGMSG("State thread created successfully.");
- //Initializing the buffer
- rc=init_buffer();
- if(rc!= SR_ERR_OK){
- SRP_LOG_DBGMSG("Problem in initializing the buffers\n");
- goto error;
- }
+ // strategies subscriptions
- SRP_LOG_DBGMSG("buffer initialized successfully.");
+ rc = sr_rpc_subscribe(session, "/hicn:strategies-get", hicn_strategies_get_cb,
+ session, 98, SR_SUBSCR_CTX_REUSE, subscription);
+ if (rc != SR_ERR_OK) {
+ SRP_LOG_DBGMSG("Problem in subscription strategies-get\n");
+ goto error;
+ }
+ // face ip subscriptions
- rc=init_face_pool(fcurrent);
- if(rc){
- SRP_LOG_DBGMSG("Problem in initializing the pools\n");
- goto error;
- }
+ rc = sr_rpc_subscribe(session, "/hicn:face-params-get",
+ hicn_face_params_get_cb, session, 93,
+ SR_SUBSCR_CTX_REUSE, subscription);
+ if (rc != SR_ERR_OK) {
+ SRP_LOG_DBGMSG("Problem in subscription face-params-get\n");
+ goto error;
+ }
+ // hICN enable-disable subscriptions
- rc=init_route_pool(rcurrent);
- if(rc){
- SRP_LOG_DBGMSG("Problem in initializing the pools\n");
- goto error;
- }
+ rc = sr_rpc_subscribe(session, "/hicn:hicn-enable", hicn_enable_cb, session,
+ 94, SR_SUBSCR_CTX_REUSE, subscription);
+ if (rc != SR_ERR_OK) {
+ SRP_LOG_DBGMSG("Problem in subscription hicn-enable\n");
+ goto error;
+ }
+ rc = sr_rpc_subscribe(session, "/hicn:hicn-disable", hicn_disable_cb, session,
+ 95, SR_SUBSCR_CTX_REUSE, subscription);
+ if (rc != SR_ERR_OK) {
+ SRP_LOG_DBGMSG("Problem in subscription hicn-enable\n");
+ goto error;
+ }
- SRP_LOG_DBGMSG("pools created successfully.");
+ // subscribe as hicn state data provider
+ rc = sr_oper_get_items_subscribe(session, "hicn", "/hicn:hicn-state/states",
+ hicn_state_states_cb, NULL,
+ SR_SUBSCR_CTX_REUSE, subscription);
+ if (rc != SR_ERR_OK) {
+ SRP_LOG_DBGMSG("Problem in subscription /hicn:hicn-state/states\n");
+ goto error;
+ }
- // Create state thread observation
- pthread_t state_tid;
- rc = pthread_create((pthread_t *)&state_tid, NULL, state_thread, NULL);
- if (rc != 0) {
- SRP_LOG_DBGMSG("Error making hicn state thread");
- return SR_ERR_OPERATION_FAILED;
- }
- SRP_LOG_DBGMSG("State thread created successfully.");
+ rc = sr_oper_get_items_subscribe(session, "hicn", "/hicn:hicn-state/routes",
+ hicn_state_route_cb, NULL,
+ SR_SUBSCR_CTX_REUSE, subscription);
+ if (rc != SR_ERR_OK) {
+ SRP_LOG_DBGMSG("Problem in subscription /hicn:hicn-state/routes\n");
+ goto error;
+ }
+ rc = sr_oper_get_items_subscribe(session, "hicn", "/hicn:hicn-state/faces",
+ hicn_state_faces_cb, NULL,
+ SR_SUBSCR_CTX_REUSE, subscription);
+ if (rc != SR_ERR_OK) {
+ SRP_LOG_DBGMSG("Problem in subscription /hicn:hicn-state/faces\n");
+ goto error;
+ }
-/*
- // subscripe for edit-config
- rc = sr_module_change_subscribe(
- session, "hicn","/hicn:hicn-conf", hicn_node_params_set_cb, g_vapi_ctx_instance,
- 0, SR_SUBSCR_CTX_REUSE | SR_SUBSCR_ENABLED, subscription);
- if (SR_ERR_OK != rc) {
- //SRP_LOG_DBGMSG("Problem in subscription /hicn:hicn-conf\n");
- perror("Problem in subscription /hicn:hicn-conf\n");
- goto error;
- }
-*/
-
- // strategies subscriptions
-
- rc = sr_rpc_subscribe(session, "/hicn:strategies-get",
- hicn_strategies_get_cb, session, 98,SR_SUBSCR_CTX_REUSE, subscription);
- if (rc!= SR_ERR_OK) {
- SRP_LOG_DBGMSG("Problem in subscription strategies-get\n");
- goto error;
- }
-
- // route nhops subscriptions
-
- rc = sr_rpc_subscribe(session, "/hicn:route-nhops-add",
- hicn_route_nhops_add_cb, session, 95,SR_SUBSCR_CTX_REUSE, subscription);
- if (rc!= SR_ERR_OK) {
- SRP_LOG_DBGMSG("Problem in subscription route-nhops-add\n");
- goto error;
- }
-
- rc = sr_rpc_subscribe(session, "/hicn:route-nhops-del",
- hicn_route_nhops_del_cb, session, 94,SR_SUBSCR_CTX_REUSE, subscription);
- if (rc!= SR_ERR_OK) {
- SRP_LOG_DBGMSG("Problem in subscription route-nhops-del\n");
- goto error;
- }
-
- rc = sr_rpc_subscribe(session, "/hicn:route-del", hicn_route_del_cb,
- session, 96,SR_SUBSCR_CTX_REUSE, subscription);
- if (rc != SR_ERR_OK) {
- SRP_LOG_DBGMSG("Problem in subscription route-del\n");
- goto error;
- }
-
- // face ip subscriptions
-
- rc = sr_rpc_subscribe(session, "/hicn:face-ip-params-get",
- hicn_face_ip_params_get_cb, session, 93,SR_SUBSCR_CTX_REUSE, subscription);
- if (rc != SR_ERR_OK) {
- SRP_LOG_DBGMSG("Problem in subscription face-ip-params-get\n");
- goto error;
- }
-
-
- rc = sr_rpc_subscribe(session, "/hicn:face-ip-add", hicn_face_ip_add_cb,
- session, 92,SR_SUBSCR_CTX_REUSE, subscription);
- if (rc != SR_ERR_OK) {
- SRP_LOG_DBGMSG("Problem in subscription face-ip-add\n");
- goto error;
- }
-
- rc = sr_rpc_subscribe(session, "/hicn:face-ip-del", hicn_face_ip_del_cb,
- session, 91,SR_SUBSCR_CTX_REUSE, subscription);
- if (rc != SR_ERR_OK) {
- SRP_LOG_DBGMSG("Problem in subscription face-ip-del\n");
- goto error;
- }
-
- // subscribe as hicn state data provider
-
- rc = sr_oper_get_items_subscribe(session, "hicn","/hicn:hicn-state/states",
- hicn_state_states_cb, NULL, SR_SUBSCR_CTX_REUSE,
- subscription);
- if (rc != SR_ERR_OK) {
- SRP_LOG_DBGMSG("Problem in subscription /hicn:hicn-state/states\n");
- goto error;
- }
-
-
- rc = sr_oper_get_items_subscribe(session, "hicn","/hicn:hicn-state/routes",
- hicn_state_route_cb, NULL, SR_SUBSCR_CTX_REUSE,
- subscription);
- if (rc != SR_ERR_OK) {
- SRP_LOG_DBGMSG("Problem in subscription /hicn:hicn-state/routes\n");
- goto error;
- }
-
-
- rc = sr_oper_get_items_subscribe(session, "hicn","/hicn:hicn-state/faces",
- hicn_state_faces_cb, NULL, SR_SUBSCR_CTX_REUSE,
- subscription);
- if (rc != SR_ERR_OK) {
- SRP_LOG_DBGMSG("Problem in subscription /hicn:hicn-state/faces\n");
- goto error;
- }
-
-
- SRP_LOG_DBGMSG("hicn plugin initialized successfully.\n");
- return SR_ERR_OK;
+ SRP_LOG_DBGMSG("hicn plugin initialized successfully.\n");
+ return SR_ERR_OK;
error:
- SRP_LOG_ERRMSG("Error by initialization of the hicn plugin.");
- sr_plugin_cleanup_cb(session, &g_vapi_ctx_instance);
- return rc;
+ SRP_LOG_ERRMSG("Error by initialization of the hicn plugin.");
+ sr_plugin_cleanup_cb(session, &g_vapi_ctx_instance);
+ return rc;
}
diff --git a/ctrl/sysrepo-plugins/yang/hicn/hicn.yang b/ctrl/sysrepo-plugins/yang/hicn/hicn.yang
index de09fcdb9..0514a7a2a 100644
--- a/ctrl/sysrepo-plugins/yang/hicn/hicn.yang
+++ b/ctrl/sysrepo-plugins/yang/hicn/hicn.yang
@@ -1,426 +1,247 @@
module hicn {
-namespace "urn:sysrepo:hicn";
-prefix hcn;
+ namespace "urn:sysrepo:hicn";
+ prefix hcn;
-
-revision 2019-10-30{
- description "revised revision focus on telemetry.";
-}
-
-/* new data types and grouping definition to forward the remote request toward hicn controler--to-->hicn */
-
-typedef float {
- type decimal64 {
- fraction-digits 2;
- }
-}
-
-grouping face_ip_add {
-
-leaf lip4 {
- description "IP version 4 local address.";
- type string;
- }
-
-leaf lip6 {
- description "IP version 6 local address.";
- type string;
- }
-
-leaf rip4 {
- description "IP version 4 local address.";
- type string;
- }
-
-leaf rip6 {
- description "IP version 6 local address.";
- type string;
- }
-
-leaf swif {
- description "Interface Index.";
- type uint32;
- }
-}
-
-grouping route_nhops_add {
-
-leaf ip4 {
- description "ip4 to be added to the FIB.";
- type string;
- }
-
-leaf ip6 {
- description "ip6 to be added to the FIB.";
- type string;
- }
-
-leaf len {
- description "Length of the prefix.";
- type uint8;
- }
-
-leaf face_ids0 {
- description "A Face ID to the next hop forwarder for the specified prefix.";
- type uint32;
- }
-
-leaf face_ids1 {
- description "A Face ID to the next hop forwarder for the specified prefix.";
- type uint32;
- }
-
-leaf face_ids2 {
- description "A Face ID to the next hop forwarder for the specified prefix.";
- type uint32;
- }
-
-leaf face_ids3 {
- description "A Face ID to the next hop forwarder for the specified prefix.";
- type uint32;
- }
-
-leaf face_ids4 {
- description "A Face ID to the next hop forwarder for the specified prefix.";
- type uint32;
- }
-
-leaf face_ids5 {
- description "A Face ID to the next hop forwarder for the specified prefix.";
- type uint32;
- }
-
-leaf face_ids6 {
- description "A Face ID to the next hop forwarder for the specified prefix.";
- type uint32;
- }
-
-leaf n_faces {
- description "Number of face to add.";
- type uint8;
- }
-}
-
-
-grouping route_nhops_del {
-
-leaf ip4 {
- description "ip4 to be added to the FIB.";
- type string;
- }
-
-leaf ip6 {
- description "ip6 to be added to the FIB.";
- type string;
- }
-
-leaf len {
- description "Length of the prefix.";
- type uint8;
- }
-
-leaf faceid {
- description "A Face ID to the next hop forwarder for the specified prefix.";
- type uint32;
- }
-
-}
-
-grouping route_del {
-
-leaf ip4 {
- description "ip4 to be added to the FIB.";
- type string;
- }
-
-leaf ip6 {
- description "ip6 to be added to the FIB.";
- type string;
- }
-
-leaf len {
- description "Length of the prefix.";
- type uint8;
- }
-}
-
-grouping punting_add_ip {
-
-leaf ip4 {
- description "ip4 to be added to the FIB.";
- type string;
- }
-
-leaf ip6 {
- description "ip6 to be added to the FIB.";
- type string;
- }
-
-leaf len {
- description "Length of the prefix.";
- type uint8;
+ import ietf-inet-types {
+ prefix inet;
}
-leaf swif {
- description "Interface id.";
- type uint32;
+ revision 2020-04-29{
+ description "revised revision focus on telemetry.";
}
-}
-
-grouping states-reply {
-
- leaf pkts_processed {
- description "ICN packets processed.";
- type uint64;
- }
-
- leaf pkts_interest_count {
- description "PIT maximum size, otherwise -1 to assign default value.";
- type uint64;
- }
-
- leaf pkts_data_count {
- description "CS maximum size, otherwise -1 to assign default value.";
- type uint64;
- }
-
- leaf pkts_from_cache_count {
- description "Portion of CS reserved to application, otherwise -1 to assign default value.";
- type uint64;
- }
-
- leaf pkts_no_pit_count {
- description "Default PIT entry lifetime, otherwise -1 to assign default value.";
- type uint64;
- }
- leaf pit_expired_count {
- description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value.";
- type uint64;
- }
-
- leaf cs_expired_count {
- description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value .";
- type uint64;
- }
-
- leaf cs_lru_count {
- description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value .";
- type uint64;
- }
+ /* new data types and grouping definition to forward the remote request toward hicn controler--to-->hicn */
- leaf pkts_drop_no_buf {
- description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value .";
- type uint64;
- }
-
- leaf interests_aggregated {
- description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value .";
- type uint64;
- }
-
- leaf interests_retx {
- description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value .";
- type uint64;
+ typedef float {
+ type decimal64 {
+ fraction-digits 2;
}
+ }
- leaf interests_hash_collision {
- description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value .";
- type uint64;
- }
+ grouping states-reply {
- leaf pit_entries_count {
- description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value .";
- type uint64;
- }
+ leaf pkts_processed {
+ description "ICN packets processed.";
+ type uint64;
+ }
- leaf cs_entries_count {
- description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value .";
- type uint64;
- }
+ leaf pkts_interest_count {
+ description "PIT maximum size, otherwise -1 to assign default value.";
+ type uint64;
+ }
- leaf cs_entries_ntw_count {
- description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value .";
- type uint64;
- }
+ leaf pkts_data_count {
+ description "CS maximum size, otherwise -1 to assign default value.";
+ type uint64;
+ }
-}
+ leaf pkts_from_cache_count {
+ description "Portion of CS reserved to application, otherwise -1 to assign default value.";
+ type uint64;
+ }
-grouping face-stats-reply {
- list face{
- key faceid;
- leaf faceid {
- description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value .";
- type uint32;
+ leaf pkts_no_pit_count {
+ description "Default PIT entry lifetime, otherwise -1 to assign default value.";
+ type uint64;
}
- leaf intfc {
- description "This is the idx number of the faceid.";
- type uint32;
+ leaf pit_expired_count {
+ description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value.";
+ type uint64;
}
- leaf irx_packets {
+ leaf cs_expired_count {
description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value .";
type uint64;
}
- leaf irx_bytes {
+ leaf cs_lru_count {
description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value .";
type uint64;
}
- leaf itx_packets {
+ leaf pkts_drop_no_buf {
description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value .";
type uint64;
}
- leaf itx_bytes {
+ leaf interests_aggregated {
description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value .";
type uint64;
}
-
- leaf drx_packets {
+ leaf interests_retx {
description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value .";
type uint64;
}
- leaf drx_bytes {
+ leaf interests_hash_collision {
description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value .";
type uint64;
}
- leaf dtx_packets {
+ leaf pit_entries_count {
description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value .";
type uint64;
}
+ leaf cs_entries_count {
+ description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value .";
+ type uint64;
+ }
- leaf dtx_bytes {
+ leaf cs_entries_ntw_count {
description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value .";
type uint64;
}
+
}
-}
-grouping route-reply {
+ grouping face-stats-reply {
+ list face{
+ key faceid;
+ leaf faceid {
+ description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value .";
+ type uint32;
+ }
- list route{
- key routeid;
- leaf routeid {
- description "the unique key for each item.";
- type uint32;
- }
- leaf prefix {
- description "IP address.";
- type string;
-
- }
- leaf strategy_id {
- description "compile-time plugin features.";
- type uint32;
- }
- }
-}
+ leaf intfc {
+ description "This is the idx number of the faceid.";
+ type uint32;
+ }
-grouping strategies-reply {
- leaf n_strategies {
- description "Enable / disable ICN forwarder in VPP.";
- type uint8;
- }
- leaf strategy_id {
- description "Enable / disable ICN forwarder in VPP.";
- type uint32;
- }
+ leaf irx_packets {
+ description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value .";
+ type uint64;
+ }
-}
+ leaf irx_bytes {
+ description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value .";
+ type uint64;
+ }
+ leaf itx_packets {
+ description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value .";
+ type uint64;
+ }
-/* Hicn operational data */
+ leaf itx_bytes {
+ description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value .";
+ type uint64;
+ }
-container hicn-state {
- config false;
- description "operational data container for the hicn.";
- container faces{
- uses face-stats-reply;
- }
- container states{
- uses states-reply;
- }
- container routes{
- uses route-reply;
- }
-}
+ leaf drx_packets {
+ description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value .";
+ type uint64;
+ }
+ leaf drx_bytes {
+ description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value .";
+ type uint64;
+ }
-/* RPC Definitions */
+ leaf dtx_packets {
+ description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value .";
+ type uint64;
+ }
-rpc strategies-get {
- description "Operation to get hicn strategies.";
-}
-rpc route-del {
- description "Operation to del hicn route.";
- input {
- uses route_del;
+ leaf dtx_bytes {
+ description "Upper bound on PIT entry lifetime, otherwise -1 to assign default value .";
+ type uint64;
+ }
+ }
}
-}
-rpc route-nhops-add {
- description "Operation to add hicn route nhops.";
- input {
- uses route_nhops_add;
+ grouping route-reply {
+
+ list route{
+ key routeid;
+ leaf routeid {
+ description "the unique key for each item.";
+ type uint32;
+ }
+ leaf prefix {
+ description "IP address.";
+ type string;
+
+ }
+ leaf strategy_id {
+ description "compile-time plugin features.";
+ type uint32;
+ }
}
-}
+ }
+
+ grouping strategies-reply {
+ leaf n_strategies {
+ description "Enable / disable ICN forwarder in VPP.";
+ type uint8;
+ }
+ leaf strategy_id {
+ description "Enable / disable ICN forwarder in VPP.";
+ type uint32;
+ }
-rpc route-nhops-del {
- description "Operation to add hicn face ip punt.";
- input {
- uses route_nhops_del;
}
-}
-rpc face-ip-params-get {
- description "Operation to del hicn route.";
- input {
- leaf faceid {
- description "Face to be retrieved .";
- type uint32;
+ typedef hicn-prefix {
+ description "hICN prefix.";
+ type inet:ip-prefix;
+ }
+
+
+ /* Hicn operational data */
+
+ container hicn-state {
+
+ config false;
+ description "operational data container for the hicn.";
+ container faces{
+ uses face-stats-reply;
+ }
+ container states{
+ uses states-reply;
+ }
+ container routes{
+ uses route-reply;
}
}
-}
-rpc face-ip-add {
- description "Operation to add hicn face ip.";
- input {
- uses face_ip_add;
+
+ /* RPC Definitions */
+
+ rpc strategies-get {
+ description "Operation to get hicn strategies.";
}
-}
-rpc face-ip-del {
- description "Operation to del hicn face ip.";
- input {
- leaf faceid {
- description "Face to be deleted .";
- type uint32;
+ rpc face-params-get {
+ description "Operation to del hicn route.";
+ input {
+ leaf faceid {
+ description "Face to be retrieved .";
+ type uint32;
+ }
}
}
-}
-rpc punting-add-ip {
- description "Operation to add hicn punt.";
- input {
- uses punting_add_ip;
+ rpc hicn-enable {
+ description "Enable hicn on a gie prefix.";
+ input {
+ leaf prefix {
+ type hicn-prefix;
+ }
+ }
}
-}
-rpc punting-del-ip {
- description "Operation to del hicn punt.";
- input {
- uses punting_add_ip; /* It uses the same payload as the add*/
+ rpc hicn-disable {
+ description "Disable hicn on a gie prefix.";
+ input {
+ leaf prefix {
+ type hicn-prefix;
+ }
+ }
}
-}
-
}
diff --git a/lib/doc/CMakeLists.txt b/docs/doxygen/CMakeLists.txt
index 135addc09..8da74995b 100644
--- a/lib/doc/CMakeLists.txt
+++ b/docs/doxygen/CMakeLists.txt
@@ -7,7 +7,7 @@ if(BUILD_DOCUMENTATION)
message(FATAL_ERROR "Doxygen is needed to build the documentation.")
endif()
- set(doxy_main_page ${CMAKE_CURRENT_SOURCE_DIR}/../README.md)
+ set(doxy_main_page ${CMAKE_CURRENT_SOURCE_DIR}/../../README.md)
set(doxyfile_in ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in)
set(doxyfile ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
diff --git a/lib/doc/Doxyfile.in b/docs/doxygen/Doxyfile.in
index a28fb3a1a..6f152323d 100644
--- a/lib/doc/Doxyfile.in
+++ b/docs/doxygen/Doxyfile.in
@@ -1,4 +1,4 @@
-PROJECT_NAME = "Hybrid ICN (hICN)"
+PROJECT_NAME = "Hybrid ICN (hICN) plugin"
PROJECT_NUMBER = @VERSION@
STRIP_FROM_PATH = @PROJECT_SOURCE_DIR@ \
@PROJECT_BINARY_DIR@
@@ -7,6 +7,6 @@ INPUT = @doxy_main_page@ \
@PROJECT_BINARY_DIR@
FILE_PATTERNS = *.md \
*.h \
- *.cc
+ *.hpp
RECURSIVE = YES
USE_MDFILE_AS_MAINPAGE = @doxy_main_page@
diff --git a/docs/source/control.md b/docs/source/control.md
index 07010a8d1..9564a23af 100644
--- a/docs/source/control.md
+++ b/docs/source/control.md
@@ -149,60 +149,17 @@ controler_rpcs_instances.xml in the yang-model. Here you can find the content:
<len>30</len>
</route-get>
-<route-del xmlns="urn:sysrepo:hicn">
- <prefix0>10</prefix0>
- <prefix1>20</prefix1>
- <len>30</len>
-</route-del>
-
-<route-nhops-add xmlns="urn:sysrepo:hicn">
- <prefix0>10</prefix0>
- <prefix1>20</prefix1>
- <len>30</len>
- <face_ids0>40</face_ids0>
- <face_ids1>50</face_ids1>
- <face_ids2>60</face_ids2>
- <face_ids3>70</face_ids3>
- <face_ids4>80</face_ids4>
- <face_ids5>90</face_ids5>
- <face_ids6>100</face_ids6>
- <n_faces>110</n_faces>
-</route-nhops-add>
-
-<route-nhops-del xmlns="urn:sysrepo:hicn">
- <prefix0>10</prefix0>
- <prefix1>20</prefix1>
- <len>30</len>
- <faceid>40</faceid>
-</route-nhops-del>
-
-<face-ip-params-get xmlns="urn:sysrepo:hicn">
+<face-params-get xmlns="urn:sysrepo:hicn">
<faceid>10</faceid>
-</face-ip-params-get>
-
-<face-ip-add xmlns="urn:sysrepo:hicn">
- <nh_addr0>10</nh_addr0>
- <nh_addr1>20</nh_addr1>
- <swif>30</swif>
-</face-ip-add>
+</face-params-get>
-<face-ip-del xmlns="urn:sysrepo:hicn">
- <faceid>0</faceid>
-</face-ip-del>
+<hicn-enable xmlns="urn:sysrepo:hicn">
+ <prefix>b001::/64</prefix>
+</hicn-enable>
-<punting-add xmlns="urn:sysrepo:hicn">
- <prefix0>10</prefix0>
- <prefix1>20</prefix1>
- <len>30</len>
- <swif>40</swif>
-</punting-add>
-
-<punting-del xmlns="urn:sysrepo:hicn">
- <prefix0>10</prefix0>
- <prefix1>20</prefix1>
- <len>30</len>
- <swif>40</swif>
-</punting-del>
+<hicn-disable xmlns="urn:sysrepo:hicn">
+ <prefix>b001::/64</prefix>
+</hicn-disable>
```
#### Run the plugin
diff --git a/docs/source/vpp-plugin.md b/docs/source/vpp-plugin.md
index f93479da8..7f49cd8b9 100644
--- a/docs/source/vpp-plugin.md
+++ b/docs/source/vpp-plugin.md
@@ -188,40 +188,6 @@ sudo vppctl
vpp# hicn ?
```
-`hicn control param`: configures the internal parameter of the hICN plugin.
-This command must be run before hicn control start.
-
-```bash
-hicn control param { pit { size <entries> | { dfltlife | minlife | maxlife } <seconds> } | cs {size <entries> | app <portion to reserved to app>} }
- <entries> :set the maximum number of entry in the PIT or CS. Default for PIT is 131072, for CS is 4096. CS size cannot be grater than PIT size. Moreover CS size must be smaller than (# of vlib buffer - 8196).
- <seconds> :set the default, maximum or minimum lifetime of pit entries. Default value 2s (default), 0.2s (minumum), 20s (maximum)
- <portion to reserved to app> :set the portion of CS to reserve to application running locally on the forwarder. Default is 30% of the cs size.
-```
-
-`hicn control start`: starts the hICN plugin in VPP.
-
-`hicn control stop` : stops the hICN plugin in VPP. Currently not supported.
-
-`hicn face app` : manipulates producer and consumer application faces in the forwarder.
-
-```bash
-hicn face app {add intfc <sw_if> {prod prefix <hicn_prefix> cs_size <size_in_packets>} {cons}} | {del <face_id>}
- <sw_if> :software interface existing in vpp on top of which to create an application face
- <hicn_prefix> :prefix to bound to the producer application face. Only content matching the prefix will be allowed through such face.
- <size_in_packets> :content store size associated to the producer face.
- <face_id> :id of the face to remove
-```
-
-`hicn face ip`: manipulates ip application faces in the forwarder.
-
-```bash
-hicn face ip {add [local <src_address>] remote <dst_address> intfc <sw_if>} | {del id <face_id>}
- <src_address> :the IPv4 or IPv6 local IP address to bind to (not mandatory, if not specified the local address is one of the address assigned to sw_if)
- <dst_address> :the IPv4 or IPv6 address of the remote system
- <sw_if> :software interface on thop of which we create the face
- <face_id> :id of the face to remove
-```
-
`hicn face show`: list the available faces in the forwarder.
```bash
@@ -230,28 +196,6 @@ hicn face show [<face_id>| type <ip/udp>]
<ip/udp> :shows all the ip or udp faces available
```
-`hicn face udp`: manipulates udp application faces in the forwarder.
-
-```bash
-hicn face udp {add src_addr <src_address> port <src_port > dst_addr <dst_address> port <dst_port>} intfc <sw_if> | {del id <face_id>}
- <src_address> :the IPv4 or IPv6 local IP address to bind to
- <src_port> :the local UDP port
- <dst_address> :the IPv4 or IPv6 address of the remote system
- <dst_port> :the remote UDP port
- <sw_if> :software interface on thop of which we create the face
- <face_id> :id of the face to remove
-
-```
-
-`hicn fib`: manipulates hicn fib entries.
-
-```bash
-hicn fib {{add | delete } prefix <prefix> face <face_id> } | set strategy <strategy_id> prefix <prefix>
- <prefix> :prefix to add to the FIB
- <face_id> :face id to add as nexto hop in the FIB entry
- <strategy_id> :set a strategy for the corresponding prefix
-```
-
`hicn pgen client`: set an vpp forwarder as an hicn packet generator client.
```bash
@@ -291,6 +235,21 @@ hicn strategy mw set prefix <prefix> face <face_id> weight <weight>
<weight> :weight
```
+`hicn enable`: enable hICN forwarding pipeline for an ip prefix.
+
+```bash
+hicn enable <prefix>
+ <prefix> :prefix for which the hICN forwarding pipeline is enabled
+```
+
+`hicn disable`: disable hICN forwarding pipeline for an ip prefix.
+
+```bash
+hicn enable <prefix>
+ <prefix> :prefix for which the hICN forwarding pipeline is disable
+```
+
+
#### hICN plugin configuration file
A configuration can be use to setup the hicn plugin when vpp starts.
@@ -328,10 +287,8 @@ forwarders are connected through a dpdk link.
sudo vppctl
vpp# set interface ip address TenGigabitEtherneta/0/0 2001::2/64
vpp# set interface state TenGigabitEtherneta/0/0 up
-vpp# hicn control start
-vpp# hicn face ip add local 2001::2 remote 2001::3 intfc TenGigabitEtherneta/0/0
-vpp# hicn fib add prefix b002::1/64 face 0
-vpp# hicn punting add prefix b002::1/64 intfc TenGigabitEtherneta/0/0 type ip
+vpp# ip route add b002::1/64 via remote 2001::3 TenGigabitEtherneta/0/0
+vpp# hicn enable b002::1/64
```
#### Forwarder B (server)
@@ -340,8 +297,6 @@ vpp# hicn punting add prefix b002::1/64 intfc TenGigabitEtherneta/0/0 type ip
sudo vppctl
vpp# set interface ip address TenGigabitEtherneta/0/1 2001::3/64
vpp# set interface state TenGigabitEtherneta/0/1 up
-vpp# hicn control start
-vpp# hicn punting add prefix b002::1/64 intfc TenGigabitEtherneta/0/1 type ip
```
Once the two forwarder are started, run the `ping_server` application on the
@@ -380,6 +335,7 @@ sudo vppctl
vpp# set interface ip address TenGigabitEtherneta/0/0 2001::2/64
vpp# set interface state TenGigabitEtherneta/0/0 up
vpp# ip route add b001::/64 via 2001::3 TenGigabitEtherneta/0/0
+vpp# ip route add 2001::3 via TenGigabitEtherneta/0/0
vpp# hicn pgen client src 2001::2 name b001::1/64 intfc TenGigabitEtherneta/0/0
vpp# exec /<path_to>pg.conf
vpp# packet-generator enable-stream hicn-pg
@@ -419,8 +375,8 @@ vpp# hicn pgen server name b001::1/64 intfc TenGigabitEtherneta/0/1
sudo vppctl
vpp# set interface ip address TenGigabitEtherneta/0/0 2001::2/64
vpp# set interface state TenGigabitEtherneta/0/0 up
-vpp# hicn face ip add remote 2001::3 intfc TenGigabitEtherneta/0/0
-vpp# hicn fib add prefix b001::/64 face 0
+vpp# ip route add b001::/64 via 2001::3 TenGigabitEtherneta/0/0
+vpp# hicn enable b001::/64
vpp# create loopback interface
vpp# set interface state loop0 up
vpp# set interface ip address loop0 5002::1/64
@@ -442,7 +398,7 @@ vpp# create loopback interface
vpp# set interface state loop0 up
vpp# set interface ip address loop0 2002::1/64
vpp# ip neighbor loop1 2002::2 de:ad:00:00:00:00
-vpp# hicn face ip add remote 2002::2 intfc loop0
-vpp# hicn fib add prefix b001::/64 face 0
+vpp# ip route add b001::/64 via 2002::2 loop0
+vpp# hicn enable b001::/64
vpp# hicn pgen server name b001::1/64 intfc loop0
```
diff --git a/hicn-plugin/src/CMakeLists.txt b/hicn-plugin/src/CMakeLists.txt
index 6852b95bb..ebe8f8713 100644
--- a/hicn-plugin/src/CMakeLists.txt
+++ b/hicn-plugin/src/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2017-2019 Cisco and/or its affiliates.
+# Copyright (c) 2017-2020 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:
@@ -75,20 +75,11 @@ set(HICN_PLUGIN_SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/data_input_node.c
${CMAKE_CURRENT_SOURCE_DIR}/data_pcslookup_node.c
${CMAKE_CURRENT_SOURCE_DIR}/data_fwd_node.c
- ${CMAKE_CURRENT_SOURCE_DIR}/data_push_node.c
${CMAKE_CURRENT_SOURCE_DIR}/error.c
${CMAKE_CURRENT_SOURCE_DIR}/faces/face_cli.c
${CMAKE_CURRENT_SOURCE_DIR}/faces/face.c
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/ip/face_ip.c
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/ip/face_ip_cli.c
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/ip/face_ip_node.c
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/ip/iface_ip_node.c
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/ip/dpo_ip.c
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/udp/face_udp.c
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/udp/face_udp_cli.c
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/udp/face_udp_node.c
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/udp/iface_udp_node.c
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/udp/dpo_udp.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/faces/face_node.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/faces/iface_node.c
${CMAKE_CURRENT_SOURCE_DIR}/faces/app/address_mgr.c
${CMAKE_CURRENT_SOURCE_DIR}/faces/app/face_cons.c
${CMAKE_CURRENT_SOURCE_DIR}/faces/app/face_prod.c
@@ -104,6 +95,8 @@ set(HICN_PLUGIN_SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/mapme_ack_node.c
${CMAKE_CURRENT_SOURCE_DIR}/mapme_ctrl_node.c
${CMAKE_CURRENT_SOURCE_DIR}/mapme_eventmgr.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/udp_tunnels/udp_decap_node.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/udp_tunnels/udp_tunnel.c
)
set(HICN_PLUGIN_HEADER_FILES
@@ -130,14 +123,9 @@ 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/ip/face_ip.h
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/ip/face_ip_node.h
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/ip/iface_ip_node.h
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/ip/dpo_ip.h
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/udp/face_udp.h
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/udp/face_udp_node.h
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/udp/iface_udp_node.h
- ${CMAKE_CURRENT_SOURCE_DIR}/faces/udp/dpo_udp.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/faces/face_node.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/faces/iface_node.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/faces/face_dpo.h
${CMAKE_CURRENT_SOURCE_DIR}/faces/app/address_mgr.h
${CMAKE_CURRENT_SOURCE_DIR}/faces/app/face_cons.h
${CMAKE_CURRENT_SOURCE_DIR}/faces/app/face_prod.h
@@ -152,6 +140,7 @@ set(HICN_PLUGIN_HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/mapme_ack.h
${CMAKE_CURRENT_SOURCE_DIR}/mapme_ctrl.h
${CMAKE_CURRENT_SOURCE_DIR}/mapme_eventmgr.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/udp_tunnels/udp_tunnel.h
)
set(HICN_API_TEST_SOURCE_FILES
@@ -165,7 +154,10 @@ set(HICN_API_HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/error.h)
set(HICN_API_GENERATED_FILES
- ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api.h)
+ ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api.h
+ ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api_types.h
+ ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api_enum.h
+)
set(HICN_VAPI_GENERATED_FILES
${CMAKE_CURRENT_BINARY_DIR}/vapi/hicn.api.vapi.h
@@ -194,6 +186,8 @@ endif()
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/hicn)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/vapi)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/vnet/ip)
+file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/vnet/fib)
+file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/vnet/udp)
# These files are missing from vpp binary distribution
execute_process(
@@ -214,11 +208,18 @@ execute_process(
if [ ! -e ${CMAKE_CURRENT_BINARY_DIR}/vnet/ip/ip_format_fns.h ]; then
curl https://raw.githubusercontent.com/FDio/vpp/master/src/vnet/ip/ip_format_fns.h -o ${CMAKE_CURRENT_BINARY_DIR}/vnet/ip/ip_format_fns.h;
fi;
+ if [ ! -e ${CMAKE_CURRENT_BINARY_DIR}/vnet/fib/fib_entry_track.h ]; then
+ curl https://raw.githubusercontent.com/FDio/vpp/master/src/vnet/fib/fib_entry_track.h -o ${CMAKE_CURRENT_BINARY_DIR}/vnet/fib/fib_entry_track.h;
+ fi;
+ if [ ! -e ${CMAKE_CURRENT_BINARY_DIR}/vnet/udp/udp_encap.h ]; then
+ curl https://raw.githubusercontent.com/FDio/vpp/master/src/vnet/udp/udp_encap.h -o ${CMAKE_CURRENT_BINARY_DIR}/vnet/udp/udp_encap.h;
+ fi;
+
chmod +x ${CMAKE_CURRENT_BINARY_DIR}/vapi_json_parser.py ${CMAKE_CURRENT_BINARY_DIR}/vapi_c_gen.py ${CMAKE_CURRENT_BINARY_DIR}/vapi_cpp_gen.py"
)
add_custom_command(
- OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api.h ${CMAKE_CURRENT_BINARY_DIR}/vapi/hicn.api.json
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api.h ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api_types.h ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api_enum.h ${CMAKE_CURRENT_BINARY_DIR}/vapi/hicn.api.json
COMMAND ${VPP_HOME}/bin/vppapigen ARGS --includedir ${CMAKE_CURRENT_BINARY_DIR} --input ${CMAKE_CURRENT_SOURCE_DIR}/hicn.api --output ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/hicn.api.h --outputdir ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins/hicn/
COMMAND ${VPP_HOME}/bin/vppapigen ARGS JSON --includedir ${CMAKE_CURRENT_BINARY_DIR} --input ${CMAKE_CURRENT_SOURCE_DIR}/hicn.api --output ${CMAKE_CURRENT_BINARY_DIR}/vapi/hicn.api.json --outputdir ${CMAKE_CURRENT_BINARY_DIR}/vapi/
)
diff --git a/hicn-plugin/src/cache_policies/cs_lru.h b/hicn-plugin/src/cache_policies/cs_lru.h
index 0a58912d6..3bd18060d 100644
--- a/hicn-plugin/src/cache_policies/cs_lru.h
+++ b/hicn-plugin/src/cache_policies/cs_lru.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -20,6 +20,13 @@
#include "../hashtb.h"
#include "cs_policy.h"
+/**
+ * @file cs_lru.h
+ *
+ * This file implements the LRU policy for the CS
+ */
+
+
extern hicn_cs_policy_vft_t hicn_cs_lru;
/*
diff --git a/hicn-plugin/src/cache_policies/cs_policy.h b/hicn-plugin/src/cache_policies/cs_policy.h
index c1a9a44c9..0bf745915 100644
--- a/hicn-plugin/src/cache_policies/cs_policy.h
+++ b/hicn-plugin/src/cache_policies/cs_policy.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -18,6 +18,13 @@
#include "../hashtb.h"
+/**
+ * @file cs_policy.h
+ *
+ * This file provides the needed structures to implement a CS policy
+ */
+
+
/*
* Structure
*/
@@ -41,7 +48,12 @@ struct hicn_cs_policy_s;
/**
* @brief Definition of the virtual functin table for a cache policy.
*
- * A cache policy must implement three functions: insert, update, delete, trim.
+ * A cache policy must implement all the following functions:
+ * - insert: add a new element
+ * - update: update the position of an existing element
+ * - dequeue: remove an element from the list
+ * - delete_get: return the next element that should be removed trim
+ * - flush: clean the cs
*/
typedef struct hicn_cs_policy_vft_s
{
diff --git a/hicn-plugin/src/cli.c b/hicn-plugin/src/cli.c
index 15ea90c96..a555d7143 100644
--- a/hicn-plugin/src/cli.c
+++ b/hicn-plugin/src/cli.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -39,7 +39,6 @@ static vl_api_hicn_api_node_params_set_t node_ctl_params = {
.pit_max_size = -1,
.pit_max_lifetime_sec = -1.0f,
.cs_max_size = -1,
- .cs_reserved_app = -1,
};
typedef enum
@@ -63,7 +62,7 @@ hicn_cli_node_ctl_start_set_command_fn (vlib_main_t * vm,
node_ctl_params.
pit_max_lifetime_sec,
node_ctl_params.cs_max_size,
- node_ctl_params.cs_reserved_app);
+ ~0);
vlib_cli_output (vm, "hicn: fwdr initialize => %s\n",
get_error_string (ret));
@@ -107,7 +106,7 @@ hicn_cli_node_ctl_stop_set_command_fn (vlib_main_t * vm,
node_ctl_params.
pit_max_lifetime_sec,
node_ctl_params.cs_max_size,
- node_ctl_params.cs_reserved_app);
+ ~0);
return (ret == HICN_ERROR_NONE) ? 0 : clib_error_return (0,
get_error_string
@@ -135,7 +134,6 @@ hicn_cli_node_ctl_param_set_command_fn (vlib_main_t * vm,
int table_size;
f64 lifetime;
- int cs_reserved_app;
if (hicn_main.is_enabled)
{
@@ -193,15 +191,6 @@ hicn_cli_node_ctl_param_set_command_fn (vlib_main_t * vm,
}
node_ctl_params.cs_max_size = table_size;
}
- else if (unformat (line_input, "app %d", &cs_reserved_app))
- {
- if (!DFLTD_RANGE_OK (cs_reserved_app, 0, 100))
- {
- rv = HICN_ERROR_CS_CONFIG_SIZE_OOB;
- break;
- }
- node_ctl_params.cs_reserved_app = cs_reserved_app;
- }
else
{
rv = HICN_ERROR_CLI_INVAL;
@@ -278,8 +267,7 @@ hicn_cli_show_command_fn (vlib_main_t * vm, unformat_input_t * main_input,
{
if (node_ctl_params.pit_max_size == -1 &&
node_ctl_params.pit_max_lifetime_sec == -1 &&
- node_ctl_params.cs_max_size == -1 &&
- node_ctl_params.cs_reserved_app == -1)
+ node_ctl_params.cs_max_size == -1)
{
ret = HICN_ERROR_FWD_NOT_ENABLED;
goto done;
@@ -302,11 +290,6 @@ hicn_cli_show_command_fn (vlib_main_t * vm, unformat_input_t * main_input,
vlib_cli_output (vm, " CS:: max entries:%d\n",
node_ctl_params.cs_max_size);
}
- if (node_ctl_params.cs_reserved_app != -1)
- {
- vlib_cli_output (vm, " CS:: reserved to app:%d\n",
- node_ctl_params.cs_reserved_app);
- }
goto done;
}
/* Globals */
@@ -314,16 +297,11 @@ hicn_cli_show_command_fn (vlib_main_t * vm, unformat_input_t * main_input,
"Forwarder: %sabled\n"
" PIT:: max entries:%d,"
" lifetime default: max:%05.3f\n"
- " CS:: max entries:%d, network entries:%d, app entries:%d (allocated %d, free %d)\n",
+ " CS:: max entries:%d\n",
hicn_main.is_enabled ? "en" : "dis",
hicn_infra_pit_size,
((f64) hicn_main.pit_lifetime_max_ms) / SEC_MS,
- hicn_infra_cs_size,
- hicn_infra_cs_size - hicn_main.pitcs.pcs_app_max,
- hicn_main.pitcs.pcs_app_max,
- hicn_main.pitcs.pcs_app_count,
- hicn_main.pitcs.pcs_app_max -
- hicn_main.pitcs.pcs_app_count);
+ hicn_infra_cs_size);
vl_api_hicn_api_node_stats_get_reply_t rm = { 0, }
, *rmp = &rm;
@@ -388,17 +366,16 @@ done:
* cli handler for 'fib'
*/
static clib_error_t *
-hicn_cli_fib_set_command_fn (vlib_main_t * vm, unformat_input_t * main_input,
- vlib_cli_command_t * cmd)
+hicn_cli_strategy_set_command_fn (vlib_main_t * vm, unformat_input_t * main_input,
+ vlib_cli_command_t * cmd)
{
clib_error_t *cl_err = 0;
int rv = HICN_ERROR_NONE;
int addpfx = -1;
ip46_address_t address;
- hicn_face_id_t faceid = HICN_FACE_NULL;
u32 strategy_id;
- u8 plen = 0;
+ u32 plen = 0;
fib_prefix_t prefix;
/* Get a line of input. */
@@ -409,15 +386,7 @@ hicn_cli_fib_set_command_fn (vlib_main_t * vm, unformat_input_t * main_input,
}
while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
{
- if (addpfx == -1 && unformat (line_input, "add"))
- {
- addpfx = 1;
- }
- else if (addpfx == -1 && unformat (line_input, "delete"))
- {
- addpfx = 0;
- }
- else if (unformat (line_input, "set strategy %d", &strategy_id))
+ if (unformat (line_input, "set %d", &strategy_id))
{
addpfx = 2;
}
@@ -426,9 +395,6 @@ hicn_cli_fib_set_command_fn (vlib_main_t * vm, unformat_input_t * main_input,
&address, IP46_TYPE_ANY, &plen))
{;
}
- else if (addpfx <= 1 && unformat (line_input, "face %u", &faceid))
- {;
- }
else
{
cl_err = clib_error_return (0, "%s '%U'",
@@ -441,63 +407,18 @@ hicn_cli_fib_set_command_fn (vlib_main_t * vm, unformat_input_t * main_input,
fib_prefix_from_ip46_addr (&address, &prefix);
prefix.fp_len = plen;
/* Check parse */
- if (addpfx <= 1
- && ((ip46_address_is_zero (&prefix.fp_addr))
- || faceid == HICN_FACE_NULL))
- {
- cl_err =
- clib_error_return (0, "Please specify prefix and a valid faceid...");
- goto done;
- }
- /* Check parse */
- if ((ip46_address_is_zero (&prefix.fp_addr))
- || (addpfx == 2 && hicn_dpo_strategy_id_is_valid (strategy_id)))
+ if (hicn_dpo_strategy_id_is_valid (strategy_id) == HICN_ERROR_DPO_MGR_ID_NOT_VALID)
{
cl_err = clib_error_return (0,
- "Please specify prefix and strategy_id...");
+ "Please specify a valid strategy...");
goto done;
}
- if (addpfx == 0)
- {
- if (ip46_address_is_zero (&prefix.fp_addr))
- {
- cl_err = clib_error_return (0, "Please specify prefix");
- goto done;
- }
- if (faceid == HICN_FACE_NULL)
- {
- rv = hicn_route_del (&prefix);
- }
- else
- {
- rv = hicn_route_del_nhop (&prefix, faceid);
- }
- cl_err =
- (rv == HICN_ERROR_NONE) ? NULL : clib_error_return (0,
- get_error_string
- (rv));
- }
- else if (addpfx == 1)
- {
- rv = hicn_route_add (&faceid, 1, &prefix);
- if (rv == HICN_ERROR_ROUTE_ALREADY_EXISTS)
- {
- rv = hicn_route_add_nhops (&faceid, 1, &prefix);
- }
- cl_err =
- (rv == HICN_ERROR_NONE) ? NULL : clib_error_return (0,
- get_error_string
- (rv));
- }
- else if (addpfx == 2)
- {
- rv = hicn_route_set_strategy (&prefix, strategy_id);
- cl_err =
- (rv == HICN_ERROR_NONE) ? NULL : clib_error_return (0,
- get_error_string
- (rv));
- }
+ rv = hicn_route_set_strategy (&prefix, strategy_id);
+ cl_err =
+ (rv == HICN_ERROR_NONE) ? NULL : clib_error_return (0,
+ get_error_string
+ (rv));
done:
return (cl_err);
@@ -783,6 +704,98 @@ hicn_cli_pgen_server_set_command_fn (vlib_main_t * vm,
return cl_err;
}
+static clib_error_t *
+hicn_enable_command_fn (vlib_main_t * vm, unformat_input_t * main_input,
+ vlib_cli_command_t * cmd)
+{
+ clib_error_t *cl_err = 0;
+
+ int rv = HICN_ERROR_NONE;
+ fib_prefix_t pfx;
+
+ /* Get a line of input. */
+ unformat_input_t _line_input, *line_input = &_line_input;
+ if (!unformat_user (main_input, unformat_line_input, line_input))
+ {
+ return (0);
+ }
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "%U/%d",
+ unformat_ip4_address, &pfx.fp_addr.ip4, &pfx.fp_len))
+ {
+ pfx.fp_proto = FIB_PROTOCOL_IP4;
+ }
+ else if (unformat (line_input, "%U/%d",
+ unformat_ip6_address, &pfx.fp_addr.ip6, &pfx.fp_len))
+ {
+ pfx.fp_proto = FIB_PROTOCOL_IP6;
+ }
+ else
+ {
+ cl_err = clib_error_return (0, "%s '%U'",
+ get_error_string (HICN_ERROR_CLI_INVAL),
+ format_unformat_error, line_input);
+ goto done;
+ }
+ }
+ rv = hicn_route_enable(&pfx);
+ done:
+
+ cl_err =
+ (rv == HICN_ERROR_NONE) ? NULL : clib_error_return (0,
+ get_error_string
+ (rv));
+ return cl_err;
+}
+
+static clib_error_t *
+hicn_disable_command_fn (vlib_main_t * vm, unformat_input_t * main_input,
+ vlib_cli_command_t * cmd)
+{
+ clib_error_t *cl_err = 0;
+
+ int rv = HICN_ERROR_NONE;
+ fib_prefix_t pfx;
+
+ /* Get a line of input. */
+ unformat_input_t _line_input, *line_input = &_line_input;
+ if (!unformat_user (main_input, unformat_line_input, line_input))
+ {
+ return (0);
+ }
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "%U/%d",
+ unformat_ip4_address, &pfx.fp_addr.ip4, &pfx.fp_len))
+ {
+ pfx.fp_proto = FIB_PROTOCOL_IP4;
+ }
+ else if (unformat (line_input, "%U/%d",
+ unformat_ip6_address, &pfx.fp_addr.ip6, &pfx.fp_len))
+ {
+ pfx.fp_proto = FIB_PROTOCOL_IP6;
+ }
+ else
+ {
+ cl_err = clib_error_return (0, "%s '%U'",
+ get_error_string (HICN_ERROR_CLI_INVAL),
+ format_unformat_error, line_input);
+ goto done;
+ }
+ }
+
+ rv = hicn_route_disable (&pfx);
+
+ done:
+ cl_err =
+ (rv == HICN_ERROR_NONE) ? NULL : clib_error_return (0,
+ get_error_string
+ (rv));
+ return cl_err;
+}
+
+
/* cli declaration for 'control start' */
/* *INDENT-OFF* */
VLIB_CLI_COMMAND(hicn_cli_node_ctl_start_set_command, static)=
@@ -818,13 +831,12 @@ VLIB_CLI_COMMAND(hicn_cli_node_ctl_command, static)=
};
/* cli declaration for 'fib' */
-VLIB_CLI_COMMAND(hicn_cli_fib_set_command, static)=
-{
- .path = "hicn fib",
- .short_help = "hicn fib {{add | delete } prefix <prefix> face <facei_d> }"
- " | set strategy <strategy_id> prefix <prefix>",
- .function = hicn_cli_fib_set_command_fn,
-};
+VLIB_CLI_COMMAND(hicn_cli_strategy_set_command, static)=
+ {
+ .path = "hicn strategy",
+ .short_help = "hicn strategy set <strategy_id> prefix <prefix>",
+ .function = hicn_cli_strategy_set_command_fn,
+ };
/* cli declaration for 'show' */
VLIB_CLI_COMMAND(hicn_cli_show_command, static)=
@@ -853,6 +865,25 @@ VLIB_CLI_COMMAND(hicn_cli_pgen_server_set_command, static)=
.long_help = "Run hicn in packet-gen server mode\n",
.function = hicn_cli_pgen_server_set_command_fn,
};
+
+/* cli declaration for 'hicn pgen client' */
+VLIB_CLI_COMMAND(hicn_enable_command, static)=
+ {
+ .path = "hicn enable",
+ .short_help = "hicn enable <prefix>",
+ .long_help = "Enable hicn for the give prefix\n",
+ .function = hicn_enable_command_fn,
+ };
+
+/* cli declaration for 'hicn pgen client' */
+VLIB_CLI_COMMAND(hicn_disable_command, static)=
+ {
+ .path = "hicn disable",
+ .short_help = "hicn disable <prefix>",
+ .long_help = "Disable hicn for the give prefix\n",
+ .function = hicn_disable_command_fn,
+ };
+
/* *INDENT-ON* */
/*
diff --git a/hicn-plugin/src/data_fwd.h b/hicn-plugin/src/data_fwd.h
index 55434a024..d95f564c3 100644
--- a/hicn-plugin/src/data_fwd.h
+++ b/hicn-plugin/src/data_fwd.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -20,6 +20,27 @@
#include "pcs.h"
+/**
+ * @file data_fwd.h
+ *
+ * This is the node encoutered by data packets after the hicn-data-pcslookup.
+ * This node has two goals: 1) clone/copy the vlib buffer as many time as the number
+ * of faces stored in the pit entry, 2) store a clone/copy of the vlib buffer in the CS.
+ * Unless there are memory issue (no more vlib buffer available to perform cloning/copy),
+ * a single vlib buffer received might results in several vlib buffer sent to the next
+ * vlib node (hicn4-iface-output or hicn6-iface-output).
+ *
+ * It must be noted that cloning is possible only if the lentgh of the data pointed by
+ * the vlib buffer is at least 256 bytes. This is due to an imposition in the vpp source
+ * code. In all the other cases the vlib buffer is copied. Cloning is performed by advancing
+ * the vlib buffer of 256 bytes and a new vlib buffer is created and chained in from of the received
+ * buffer. Additionally, the 256 bytes removed (advanced) from the received vlib buffer are
+ * copied in the head vlib buffer. In case of multiple cloning for the same vlib buffer, this
+ * mechanism allows us to have a different hICN header for each clone (+ the same additional bytes
+ * due to the vpp restriction on cloning).
+ */
+
+
/* Trace context struct */
typedef struct
{
@@ -33,13 +54,14 @@ typedef enum
{
HICN_DATA_FWD_NEXT_V4_LOOKUP,
HICN_DATA_FWD_NEXT_V6_LOOKUP,
- HICN_DATA_FWD_NEXT_PUSH,
+ HICN_DATA_FWD_NEXT_IFACE4_OUT,
+ HICN_DATA_FWD_NEXT_IFACE6_OUT,
HICN_DATA_FWD_NEXT_ERROR_DROP,
HICN_DATA_FWD_N_NEXT,
} hicn_data_fwd_next_t;
/**
- *@brief Create a maximum of 256 clones of buffer and store them
+ * @brief Create a maximum of 256 clones of buffer and store them
* in the supplied array. Unlike the original function in the vlib
* library, we don't prevent cloning if n_buffer==1 and if
* s->current_length <= head_end_offset + CLIB_CACHE_LINE_BYTES * 2.
diff --git a/hicn-plugin/src/data_fwd_node.c b/hicn-plugin/src/data_fwd_node.c
index 1bb064fcf..c65b62454 100644
--- a/hicn-plugin/src/data_fwd_node.c
+++ b/hicn-plugin/src/data_fwd_node.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -37,11 +37,6 @@ drop_packet (vlib_main_t * vm, u32 bi0,
u32 * n_left_to_next, u32 * next0, u32 ** to_next,
u32 * next_index, vlib_node_runtime_t * node);
-always_inline void
-push_in_cache (vlib_main_t * vm, u32 bi0,
- u32 * n_left_to_next, u32 * next0, u32 ** to_next,
- u32 * next_index, vlib_node_runtime_t * node);
-
always_inline int
hicn_satisfy_faces (vlib_main_t * vm, u32 b0,
hicn_pcs_entry_t * pitp, u32 * n_left_to_next,
@@ -176,21 +171,8 @@ hicn_data_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
hicn_pcs_delete (pitcs, &pitp, &node0, vm, hash_entry0,
dpo_vft0, &hicn_dpo_id0);
-#if HICN_FEATURE_CS
- if (hicnb0->flags & HICN_BUFFER_FLAGS_FACE_IS_APP)
- {
- push_in_cache (vm, bi0, &n_left_to_next, &next0, &to_next,
- &next_index, node);
- }
- else
- {
- drop_packet (vm, bi0, &n_left_to_next, &next0, &to_next,
- &next_index, node);
- }
-#else
drop_packet (vm, bi0, &n_left_to_next, &next0, &to_next,
&next_index, node);
-#endif
stats.pit_expired_count++;
if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
@@ -348,21 +330,6 @@ drop_packet (vlib_main_t * vm, u32 bi0,
*to_next, *n_left_to_next, bi0, *next0);
}
-always_inline void
-push_in_cache (vlib_main_t * vm, u32 bi0,
- u32 * n_left_to_next, u32 * next0, u32 ** to_next,
- u32 * next_index, vlib_node_runtime_t * node)
-{
- *next0 = HICN_DATA_FWD_NEXT_PUSH;
-
- (*to_next)[0] = bi0;
- *to_next += 1;
- *n_left_to_next -= 1;
-
- vlib_validate_buffer_enqueue_x1 (vm, node, *next_index,
- *to_next, *n_left_to_next, bi0, *next0);
-}
-
always_inline int
hicn_satisfy_faces (vlib_main_t * vm, u32 bi0,
hicn_pcs_entry_t * pitp, u32 * n_left_to_next,
@@ -434,7 +401,7 @@ hicn_satisfy_faces (vlib_main_t * vm, u32 bi0,
{
vlib_buffer_t *h0, *h1;
u32 hi0, hi1;
- dpo_id_t *face0, *face1;
+ hicn_face_id_t face0, face1;
/* Prefetch for next iteration. */
{
@@ -458,10 +425,13 @@ hicn_satisfy_faces (vlib_main_t * vm, u32 bi0,
n_left_from -= 2;
clones += 2;
- next0 = face0->dpoi_next_node;
- next1 = face1->dpoi_next_node;
- vnet_buffer (h0)->ip.adj_index[VLIB_TX] = face0->dpoi_index;
- vnet_buffer (h1)->ip.adj_index[VLIB_TX] = face1->dpoi_index;
+ next0 = isv6 ? HICN_DATA_FWD_NEXT_IFACE6_OUT :
+ HICN_DATA_FWD_NEXT_IFACE4_OUT;
+ next1 = isv6 ? HICN_DATA_FWD_NEXT_IFACE6_OUT :
+ HICN_DATA_FWD_NEXT_IFACE4_OUT;
+
+ vnet_buffer (h0)->ip.adj_index[VLIB_TX] = face0;
+ vnet_buffer (h1)->ip.adj_index[VLIB_TX] = face1;
stats->pkts_data_count += 2;
@@ -499,7 +469,7 @@ hicn_satisfy_faces (vlib_main_t * vm, u32 bi0,
{
vlib_buffer_t *h0;
u32 hi0;
- dpo_id_t *face0;
+ hicn_face_id_t face0;
face0 = hicn_face_db_get_dpo_face (i++, &pitp->u.pit.faces);
@@ -511,8 +481,9 @@ hicn_satisfy_faces (vlib_main_t * vm, u32 bi0,
n_left_from -= 1;
clones += 1;
- next0 = face0->dpoi_next_node;
- vnet_buffer (h0)->ip.adj_index[VLIB_TX] = face0->dpoi_index;
+ next0 = isv6 ? HICN_DATA_FWD_NEXT_IFACE6_OUT :
+ HICN_DATA_FWD_NEXT_IFACE4_OUT;
+ vnet_buffer (h0)->ip.adj_index[VLIB_TX] = face0;
stats->pkts_data_count++;
@@ -584,7 +555,7 @@ clone_data_to_cs (vlib_main_t * vm, hicn_pit_cs_t * pitcs,
*/
hicn_buffer_t *hicnb0 = hicn_get_buffer (b0);
hicn_pit_to_cs (vm, pitcs, pitp, hash_entry, nodep, dpo_vft, hicn_dpo_id,
- &hicnb->face_dpo_id,
+ hicnb->face_id,
hicnb0->flags & HICN_BUFFER_FLAGS_FACE_IS_APP);
pitp->shared.create_time = tnow;
@@ -635,7 +606,8 @@ VLIB_REGISTER_NODE(hicn_data_fwd_node) =
.next_nodes = {
[HICN_DATA_FWD_NEXT_V4_LOOKUP] = "ip4-lookup",
[HICN_DATA_FWD_NEXT_V6_LOOKUP] = "ip6-lookup",
- [HICN_DATA_FWD_NEXT_PUSH] = "hicn-data-push",
+ [HICN_DATA_FWD_NEXT_IFACE4_OUT] = "hicn4-iface-output",
+ [HICN_DATA_FWD_NEXT_IFACE6_OUT] = "hicn6-iface-output",
[HICN_DATA_FWD_NEXT_ERROR_DROP] = "error-drop",
},
};
diff --git a/hicn-plugin/src/data_input_node.c b/hicn-plugin/src/data_input_node.c
index b8c19757c..8d20f54a6 100644
--- a/hicn-plugin/src/data_input_node.c
+++ b/hicn-plugin/src/data_input_node.c
@@ -310,7 +310,7 @@ VLIB_REGISTER_NODE(hicn_data_input_ip6) =
.n_next_nodes = HICN_DATA_INPUT_IP6_N_NEXT,
.next_nodes =
{
- [HICN_DATA_INPUT_IP6_NEXT_FACE] = "hicn-face-ip6-input",
+ [HICN_DATA_INPUT_IP6_NEXT_FACE] = "hicn6-face-input",
[HICN_DATA_INPUT_IP6_NEXT_IP6_LOCAL] = "ip6-local-end-of-arc"
},
};
@@ -681,7 +681,7 @@ VLIB_REGISTER_NODE(hicn_data_input_ip4) =
.n_next_nodes = HICN_DATA_INPUT_IP4_N_NEXT,
.next_nodes =
{
- [HICN_DATA_INPUT_IP4_NEXT_FACE] = "hicn-face-ip4-input",
+ [HICN_DATA_INPUT_IP4_NEXT_FACE] = "hicn4-face-input",
[HICN_DATA_INPUT_IP4_NEXT_IP4_LOCAL] = "ip4-local-end-of-arc"
},
};
diff --git a/hicn-plugin/src/data_pcslookup.h b/hicn-plugin/src/data_pcslookup.h
index fa75c3ac3..e3050c31c 100644
--- a/hicn-plugin/src/data_pcslookup.h
+++ b/hicn-plugin/src/data_pcslookup.h
@@ -18,6 +18,15 @@
#include "pcs.h"
+/**
+ * @file data_pcslookup.h
+ *
+ * This is the node encoutered by data packets after the hicn6-face-input or
+ * hicn4-face-input. This node performs a lookup in the pit and content store and
+ * if there is a hit in the PIT, the vlib buffer is passed to the hicn-data-fwd
+ * while if there is a hit in the CS or there isn't any hit, the packet is dropped.
+ */
+
/*
* Node context data; we think this is per-thread/instance
*/
@@ -37,9 +46,6 @@ typedef struct
typedef enum
{
- HICN_DATA_PCSLOOKUP_NEXT_V4_LOOKUP,
- HICN_DATA_PCSLOOKUP_NEXT_V6_LOOKUP,
- HICN_DATA_PCSLOOKUP_NEXT_STORE_DATA,
HICN_DATA_PCSLOOKUP_NEXT_DATA_FWD, /* This must be one position
* before the error drop!! */
HICN_DATA_PCSLOOKUP_NEXT_ERROR_DROP,
diff --git a/hicn-plugin/src/data_pcslookup_node.c b/hicn-plugin/src/data_pcslookup_node.c
index cbea07871..99af350b0 100644
--- a/hicn-plugin/src/data_pcslookup_node.c
+++ b/hicn-plugin/src/data_pcslookup_node.c
@@ -63,7 +63,6 @@ hicn_data_pcslookup_node_fn (vlib_main_t * vm,
while (n_left_from > 0 && n_left_to_next > 0)
{
vlib_buffer_t *b0;
- hicn_buffer_t *hb0;
u8 isv6;
u8 *nameptr;
u16 namelen;
@@ -100,7 +99,6 @@ hicn_data_pcslookup_node_fn (vlib_main_t * vm,
n_left_to_next -= 1;
b0 = vlib_get_buffer (vm, bi0);
- hb0 = hicn_get_buffer (b0);
next0 = HICN_DATA_PCSLOOKUP_NEXT_ERROR_DROP;
/* Incr packet counter */
@@ -126,25 +124,7 @@ hicn_data_pcslookup_node_fn (vlib_main_t * vm,
stats.pkts_data_count += 1;
-#if HICN_FEATURE_CS
- if ((res == HICN_ERROR_HASHTB_HASH_NOT_FOUND ||
- (res == HICN_ERROR_NONE && is_cs0)) &&
- ((hb0->flags & HICN_BUFFER_FLAGS_FACE_IS_APP)))
- {
- next0 = HICN_DATA_PCSLOOKUP_NEXT_STORE_DATA;
- }
- else if (res == HICN_ERROR_NONE)
- {
- /*
- * In case the result of the lookup
- * is a CS entry, the packet is
- * dropped
- */
- next0 = HICN_DATA_PCSLOOKUP_NEXT_DATA_FWD + is_cs0;
- }
- }
-#else
- if (res == HICN_ERROR_NONE)
+ if (res == HICN_ERROR_NONE)
{
/*
* In case the result of the lookup
@@ -154,7 +134,6 @@ hicn_data_pcslookup_node_fn (vlib_main_t * vm,
next0 = HICN_DATA_PCSLOOKUP_NEXT_DATA_FWD + is_cs0;
}
}
-#endif
hicn_store_internal_state (b0, name_hash, node_id0, dpo_ctx_id0,
vft_id0, hash_entry_id, bucket_id,
@@ -231,9 +210,6 @@ VLIB_REGISTER_NODE(hicn_data_pcslookup_node) =
.error_strings = hicn_data_pcslookup_error_strings,
.n_next_nodes = HICN_DATA_PCSLOOKUP_N_NEXT,
.next_nodes = {
- [HICN_DATA_PCSLOOKUP_NEXT_V4_LOOKUP] = "ip4-lookup",
- [HICN_DATA_PCSLOOKUP_NEXT_V6_LOOKUP] = "ip6-lookup",
- [HICN_DATA_PCSLOOKUP_NEXT_STORE_DATA] = "hicn-data-push",
[HICN_DATA_PCSLOOKUP_NEXT_DATA_FWD] = "hicn-data-fwd",
[HICN_DATA_PCSLOOKUP_NEXT_ERROR_DROP] = "error-drop",
},
diff --git a/hicn-plugin/src/data_push_node.c b/hicn-plugin/src/data_push_node.c
deleted file mode 100644
index fc19362f9..000000000
--- a/hicn-plugin/src/data_push_node.c
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * Copyright (c) 2017-2019 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 "hicn.h"
-#include "parser.h"
-#include "strategy_dpo_ctx.h"
-#include "infra.h"
-#include "mgmt.h"
-#include "pcs.h"
-#include "state.h"
-
-/*
- * Node context data (to be used in all the strategy nodes); we think this is
- * per-thread/instance
- */
-typedef struct hicn_data_push_runtime_s
-{
- int id;
- hicn_pit_cs_t *pitcs;
-} hicn_data_push_runtime_t;
-
-/* Stats string values */
-static char *hicn_data_push_error_strings[] = {
-#define _(sym, string) string,
- foreach_hicnfwd_error
-#undef _
-};
-
-typedef enum
-{
- HICN_DATA_PUSH_NEXT_FWD,
- HICN_DATA_PUSH_NEXT_ERROR_DROP,
- HICN_DATA_PUSH_N_NEXT,
-} hicn_data_push_next_t;
-
-/* Trace context struct */
-typedef struct
-{
- u32 next_index;
- u32 sw_if_index;
- u8 pkt_type;
-} hicn_data_push_trace_t;
-
-vlib_node_registration_t hicn_data_push_node;
-
-always_inline void
-prep_buffer_for_cs (vlib_main_t * vm, vlib_buffer_t * b0, u8 isv6)
-{
- word buffer_advance = CLIB_CACHE_LINE_BYTES * 2;
- hicn_buffer_t *hicnb = hicn_get_buffer (b0);
-
- if (PREDICT_TRUE (b0->next_buffer == 0))
- {
- b0->total_length_not_including_first_buffer = 0;
- b0->flags &= ~VLIB_BUFFER_NEXT_PRESENT;
- }
-
- /*
- * Mark the buffer as smaller than TWO_CL. It will be stored as is in the CS, without excluding
- * the hicn_header. Cloning is not possible, it will be copied.
- */
- if (b0->current_length <= (buffer_advance + (CLIB_CACHE_LINE_BYTES * 2)))
- {
- /* In this case the packet is copied. We don't need to add a reference as no buffer are
- * chained to it.
- */
- hicnb->flags |= HICN_BUFFER_FLAGS_PKT_LESS_TWO_CL;
- }
- else
- {
- vlib_buffer_advance (b0, buffer_advance);
- }
-}
-
-always_inline int
-hicn_new_data (vlib_main_t * vm, hicn_data_push_runtime_t * rt,
- vlib_buffer_t * b0, u32 ** to_forward, u32 * n_to_forward,
- f64 tnow, u8 * nameptr, u16 namelen, u8 isv6)
-{
- int ret;
- u32 bi0 = vlib_get_buffer_index (vm, b0);
- hicn_hash_node_t *nodep;
- hicn_pcs_entry_t *pitp;
- hicn_header_t *hicn0 = vlib_buffer_get_current (b0);
- hicn_buffer_t *hicnb0 = hicn_get_buffer (b0);
- u32 node_id0 = 0;
- index_t dpo_ctx_id0 = ~0;
- u8 vft_id0 = default_dpo.hicn_dpo_get_type ();
- u8 is_cs0 = 1;
- u8 hash_entry_id = 0;
- u32 bucket_id = ~0;
- u8 bucket_is_overflow = 0;
- hicn_lifetime_t dmsg_lifetime;
-
- hicnb0 = hicn_get_buffer (b0);
- hicn_type_t type = hicnb0->type;
- hicn_ops_vft[type.l1]->get_lifetime (type, &hicn0->protocol,
- &dmsg_lifetime);
-
- if (!dmsg_lifetime)
- {
- vlib_buffer_free_one (vm, bi0);
- return HICN_ERROR_NONE;
- }
-
- /* Create PIT node and init PIT entry */
- nodep = hicn_hashtb_alloc_node (rt->pitcs->pcs_table);
- if (PREDICT_FALSE (nodep == NULL))
- {
- vlib_buffer_free_one (vm, bi0);
- /* Nothing we can do - no mem */
- return HICN_ERROR_HASHTB_NOMEM;
- }
-
- pitp = hicn_pit_get_data (nodep);
- hicn_cs_init_data (pitp);
- pitp->shared.create_time = tnow;
-
- if (dmsg_lifetime < HICN_PARAM_CS_LIFETIME_MIN
- || dmsg_lifetime > HICN_PARAM_CS_LIFETIME_MAX)
- {
- dmsg_lifetime = HICN_PARAM_CS_LIFETIME_DFLT;
- }
- pitp->shared.expire_time = hicn_pcs_get_exp_time (tnow, dmsg_lifetime);
-
- /* Store the original packet buffer in the CS node */
- pitp->u.cs.cs_pkt_buf = vlib_get_buffer_index (vm, b0);
-
- /* Set up the hash node and insert it */
- hicn_hashtb_init_node (rt->pitcs->pcs_table, nodep, nameptr, namelen);
-
-
- hicn_hash_entry_t *hash_entry;
- ret =
- hicn_pcs_cs_insert_update (vm, rt->pitcs, pitp, nodep, &hash_entry,
- hicnb0->name_hash, &node_id0, &dpo_ctx_id0,
- &vft_id0, &is_cs0, &hash_entry_id, &bucket_id,
- &bucket_is_overflow, &(hicnb0->face_dpo_id));
-
- if (ret != HICN_ERROR_NONE)
- {
- hicn_hashtb_free_node (rt->pitcs->pcs_table, nodep);
- }
-
- if (ret != HICN_ERROR_HASHTB_NOMEM)
- {
- if (!is_cs0)
- {
- ASSERT (ret != HICN_ERROR_NONE);
- hicn_store_internal_state (b0, hicnb0->name_hash, node_id0,
- dpo_ctx_id0, vft_id0, hash_entry_id,
- bucket_id, bucket_is_overflow);
-
- (*to_forward)[0] = bi0;
- *to_forward += 1;
- *n_to_forward += 1;
- }
- else
- {
- prep_buffer_for_cs (vm, b0, isv6);
- }
- }
-
- return (ret);
-
-}
-
-/*
- * ICN strategy later node for interests: - 1 packet at a time - ipv4/tcp
- * ipv6/tcp
- */
-uword
-hicn_data_push_fn (vlib_main_t * vm,
- vlib_node_runtime_t * node, vlib_frame_t * frame)
-{
-
- u32 n_left_from, *from, *to_next, n_left_to_next;
- hicn_data_push_next_t next_index;
- hicn_data_push_runtime_t *rt;
- vl_api_hicn_api_node_stats_get_reply_t stats = { 0 };
- f64 tnow;
- u32 *to_forward = NULL, *header = NULL, n_to_forward = 0;
-
- from = vlib_frame_vector_args (frame);
- n_left_from = frame->n_vectors;
- next_index = (hicn_data_push_next_t) node->cached_next_index;
- rt = vlib_node_get_runtime_data (vm, hicn_data_push_node.index);
- rt->pitcs = &hicn_main.pitcs;
-
- vec_alloc (to_forward, n_left_from);
- header = to_forward;
- /* Capture time in vpp terms */
- tnow = vlib_time_now (vm);
-
- while (n_left_from > 0)
- {
- u8 isv6;
- u8 *nameptr;
- u16 namelen;
- hicn_name_t name;
- hicn_header_t *hicn0;
- vlib_buffer_t *b0;
- u32 bi0;
- int ret0;
-
- /* Prefetch for next iteration. */
- if (n_left_from > 1)
- {
- vlib_buffer_t *b1;
- //hicn_buffer_t * hicnb1;
- b1 = vlib_get_buffer (vm, from[1]);
- CLIB_PREFETCH (b1, CLIB_CACHE_LINE_BYTES, LOAD);
- CLIB_PREFETCH (b1->data, CLIB_CACHE_LINE_BYTES, STORE);
- }
- /* Dequeue a packet buffer */
- bi0 = from[0];
- from += 1;
- n_left_from -= 1;
-
- b0 = vlib_get_buffer (vm, bi0);
-
- ret0 = hicn_data_parse_pkt (b0, &name, &namelen, &hicn0, &isv6);
- nameptr = (u8 *) (&name);
-
- if (PREDICT_TRUE (ret0 == HICN_ERROR_NONE))
- {
- hicn_new_data (vm, rt, b0, &to_forward, &n_to_forward, tnow,
- nameptr, namelen, isv6);
- stats.pkts_data_count++;
- }
-
- /* Maybe trace */
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
- (b0->flags & VLIB_BUFFER_IS_TRACED)))
- {
- hicn_data_push_trace_t *t =
- vlib_add_trace (vm, node, b0, sizeof (*t));
- t->pkt_type = HICN_PKT_TYPE_CONTENT;
- t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX];
- t->next_index = HICN_DATA_PUSH_NEXT_ERROR_DROP;
- }
- }
-
- to_forward -= n_to_forward;
- next_index = HICN_DATA_PUSH_NEXT_FWD;
-
- while (n_to_forward > 0)
- {
- vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
- while (n_to_forward > 0 && n_left_to_next > 0)
- {
- to_next[0] = to_forward[0];
- to_forward++;
- n_to_forward--;
- to_next++;
- n_left_to_next--;
- }
-
- vlib_put_next_frame (vm, node, next_index, n_left_to_next);
- }
-
- vec_free (header);
-
- vlib_node_increment_counter (vm, hicn_data_push_node.index,
- HICNFWD_ERROR_CACHED, stats.pkts_data_count);
-
- return (frame->n_vectors);
-}
-
-/* packet trace format function */
-always_inline u8 *
-hicn_data_push_format_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 *);
- hicn_data_push_trace_t *t = va_arg (*args, hicn_data_push_trace_t *);
-
- s = format (s, "DATA-STORE: pkt: %d, sw_if_index %d, next index %d\n",
- (int) t->pkt_type, t->sw_if_index, t->next_index);
-
- return (s);
-}
-
-
-/*
- * Node registration for the data forwarder node
- */
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE(hicn_data_push_node) =
-{
- .function = hicn_data_push_fn,
- .name = "hicn-data-push",
- .vector_size = sizeof(u32),
- .runtime_data_bytes = sizeof(hicn_data_push_runtime_t),
- .format_trace = hicn_data_push_format_trace,
- .type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN(hicn_data_push_error_strings),
- .error_strings = hicn_data_push_error_strings,
- .n_next_nodes = HICN_DATA_PUSH_N_NEXT,
- .next_nodes = {
- [HICN_DATA_PUSH_NEXT_FWD] = "hicn-data-fwd",
- [HICN_DATA_PUSH_NEXT_ERROR_DROP] = "error-drop",
- },
-};
-/* *INDENT-ON* */
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables: eval: (c-set-style "gnu") End:
- */
diff --git a/hicn-plugin/src/error.h b/hicn-plugin/src/error.h
index 2124e63c5..59ebce61c 100644
--- a/hicn-plugin/src/error.h
+++ b/hicn-plugin/src/error.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -16,6 +16,13 @@
#ifndef __HICN_ERROR_H__
#define __HICN_ERROR_H__
+/**
+ * @file error.h
+ *
+ * Error codes for the hICN plugin.
+ */
+
+
#define foreach_hicn_error \
_(NONE, 0, "Ok") \
_(UNSPECIFIED, -128, "Unspecified Error") \
@@ -69,8 +76,9 @@
_(APPFACE_PROD_PREFIX_NULL, -176, "Prefix must not be null for producer face") \
_(STRATEGY_NH_NOT_FOUND, -177, "Next hop not found") \
_(MW_STRATEGY_SET, -178, "Error while setting weight for next hop") \
- _(STRATEGY_NOT_FOUND, -179, "Strategy not found")
-
+ _(STRATEGY_NOT_FOUND, -179, "Strategy not found") \
+ _(UDP_TUNNEL_NOT_FOUND, -180, "Udp tunnel not found") \
+ _(UDP_TUNNEL_SRC_DST_TYPE, -181, "Src and dst addresses have different type (ipv4 and ipv6)")
typedef enum
{
diff --git a/hicn-plugin/src/face_db.h b/hicn-plugin/src/face_db.h
index 17c28959a..4dd8b2f32 100644
--- a/hicn-plugin/src/face_db.h
+++ b/hicn-plugin/src/face_db.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -20,7 +20,7 @@
#include "faces/face.h"
/**
- * @File
+ * @file face_db.h
*
* Define a face db that is store in every pit entry. A face db containes a list
* of incoming faces for interest packets that are used to forward data packets
@@ -28,7 +28,7 @@
*/
/* Must be power of two */
-#define HICN_FACE_DB_INLINE_FACES 4
+#define HICN_FACE_DB_INLINE_FACES 8
#define HICN_PIT_BITMAP_SIZE_BYTE HICN_PARAM_FACES_MAX/8
#define HICN_PIT_N_HOP_BITMAP_SIZE HICN_PARAM_FACES_MAX
@@ -38,7 +38,7 @@
typedef struct hicn_face_bucket_s
{
/* Array of indexes of virtual faces */
- dpo_id_t faces[HICN_PIT_N_HOP_BUCKET];
+ hicn_face_id_t faces[HICN_PIT_N_HOP_BUCKET];
/* Used to check if interests are retransmission */
u8 bitmap[HICN_PIT_BITMAP_SIZE_BYTE];
@@ -60,7 +60,7 @@ typedef struct __attribute__ ((packed)) hicn_face_db_s
/* 24B + 32B (8*4) = 56B */
/* Array of indexes of virtual faces */
- dpo_id_t inline_faces[HICN_FACE_DB_INLINE_FACES];
+ hicn_face_id_t inline_faces[HICN_FACE_DB_INLINE_FACES];
/* 56B + 4B = 60B */
u32 next_bucket;
@@ -71,13 +71,13 @@ typedef struct __attribute__ ((packed)) hicn_face_db_s
} hicn_face_db_t;
-always_inline dpo_id_t *
+always_inline hicn_face_id_t
hicn_face_db_get_dpo_face (u32 index, hicn_face_db_t * face_db)
{
ASSERT (index < face_db->n_faces);
- return index < HICN_FACE_DB_INLINE_FACES ? &(face_db->inline_faces[index]) :
- &(pool_elt_at_index (hicn_face_bucket_pool, face_db->next_bucket)->faces
+ return index < HICN_FACE_DB_INLINE_FACES ? (face_db->inline_faces[index]) :
+ (pool_elt_at_index (hicn_face_bucket_pool, face_db->next_bucket)->faces
[(index - HICN_FACE_DB_INLINE_FACES) & (HICN_PIT_N_HOP_BUCKET - 1)]);
}
@@ -94,23 +94,23 @@ hicn_face_db_get_bucket (u32 bucket_index)
}
always_inline void
-hicn_face_db_add_face_dpo (dpo_id_t * dpo, hicn_face_db_t * face_db)
+hicn_face_db_add_face (hicn_face_id_t face_id, hicn_face_db_t * face_db)
{
- ASSERT (dpo->dpoi_index != ~0);
+ //ASSERT (dpo->dpoi_index != ~0);
hicn_face_bucket_t *faces_bkt =
pool_elt_at_index (hicn_face_bucket_pool, face_db->next_bucket);
- dpo_id_t *face =
+ hicn_face_id_t *element =
face_db->n_faces <
HICN_FACE_DB_INLINE_FACES ? &(face_db->inline_faces[face_db->n_faces]) :
&(faces_bkt->faces
[(face_db->n_faces -
HICN_FACE_DB_INLINE_FACES) & (HICN_PIT_N_HOP_BUCKET - 1)]);
- clib_memcpy (face, dpo, sizeof (dpo_id_t));
+ *element = face_id;
- u32 bitmap_index = dpo->dpoi_index % HICN_PIT_N_HOP_BITMAP_SIZE;
+ u32 bitmap_index = face_id % HICN_PIT_N_HOP_BITMAP_SIZE;
u32 position_array = bitmap_index / 8;
u8 bit_index = (u8) (bitmap_index - position_array * 8);
@@ -119,11 +119,11 @@ hicn_face_db_add_face_dpo (dpo_id_t * dpo, hicn_face_db_t * face_db)
}
always_inline u8
-hicn_face_search (dpo_id_t * dpo, hicn_face_db_t * face_db)
+hicn_face_search (hicn_face_id_t index, hicn_face_db_t * face_db)
{
hicn_face_bucket_t *faces_bkt =
pool_elt_at_index (hicn_face_bucket_pool, face_db->next_bucket);
- u32 bitmap_index = dpo->dpoi_index % HICN_PIT_N_HOP_BITMAP_SIZE;
+ u32 bitmap_index = index % HICN_PIT_N_HOP_BITMAP_SIZE;
u32 position_array = bitmap_index / 8;
u8 bit_index = bitmap_index - position_array * 8;
diff --git a/hicn-plugin/src/faces/app/address_mgr.c b/hicn-plugin/src/faces/app/address_mgr.c
index 1674379c4..2d5894ab8 100644
--- a/hicn-plugin/src/faces/app/address_mgr.c
+++ b/hicn-plugin/src/faces/app/address_mgr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -36,7 +36,6 @@
#include "../../infra.h"
#include "../../error.h"
#include "../face.h"
-#include "../ip/face_ip.h"
#include "../../strategy_dpo_ctx.h"
#include "../../route.h"
@@ -134,26 +133,25 @@ get_two_ip6_addresses (ip6_address_t * appif_addr, ip6_address_t * nh_addr)
fib_pfx.fp_proto = FIB_PROTOCOL_IP6;
fib_pfx.fp_len = ADDR_MGR_IP6_LEN;
+
+ fib_index = fib_table_find (fib_pfx.fp_proto, 0);
+
/* At this point the face exists in the face table */
do
{
/* Check if the route already exist in the fib */
fib_pfx.fp_addr = to_ip46 ( /* is_v6 */ 1, appif_addr->as_u8);
- fib_index = fib_table_find_or_create_and_lock (fib_pfx.fp_proto,
- HICN_FIB_TABLE,
- FIB_SOURCE_PRIORITY_HI);
+
fib_entry_index = fib_table_lookup_exact_match (fib_index, &fib_pfx);
- fib_table_unlock (fib_index, fib_pfx.fp_proto, FIB_SOURCE_PRIORITY_HI);
+ //fib_table_unlock (fib_index, fib_pfx.fp_proto, FIB_SOURCE_PRIORITY_HI);
if (fib_entry_index != FIB_NODE_INDEX_INVALID)
{
fib_pfx.fp_addr = to_ip46 ( /* is_v6 */ 0, nh_addr->as_u8);
- fib_index = fib_table_find_or_create_and_lock (fib_pfx.fp_proto,
- HICN_FIB_TABLE,
- FIB_SOURCE_PRIORITY_HI);
+
fib_entry_index =
fib_table_lookup_exact_match (fib_index, &fib_pfx);
- fib_table_unlock (fib_index, fib_pfx.fp_proto,
- FIB_SOURCE_PRIORITY_HI);
+ // fib_table_unlock (fib_index, fib_pfx.fp_proto,
+ // FIB_SOURCE_PRIORITY_HI);
}
if (fib_entry_index != FIB_NODE_INDEX_INVALID)
{
diff --git a/hicn-plugin/src/faces/app/face_app_cli.c b/hicn-plugin/src/faces/app/face_app_cli.c
index 1e8eb6a5b..1aa27adc7 100644
--- a/hicn-plugin/src/faces/app/face_app_cli.c
+++ b/hicn-plugin/src/faces/app/face_app_cli.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -18,8 +18,7 @@
#include <vlib/vlib.h>
#include <vnet/ip/ip6_packet.h>
-#include "../ip/face_ip.h"
-#include "../ip/dpo_ip.h"
+//#include "../face_dpo.h"
#include "../face.h"
#include "face_prod.h"
#include "face_cons.h"
@@ -164,7 +163,7 @@ hicn_face_app_cli_set_command_fn (vlib_main_t * vm,
{
hicn_face_t *face = hicn_dpoi_get_from_idx (face_id1);
- if (face->shared.flags & HICN_FACE_FLAGS_APPFACE_CONS)
+ if (face->flags & HICN_FACE_FLAGS_APPFACE_CONS)
rv = hicn_face_cons_del (face_id1);
else
rv = hicn_face_prod_del (face_id1);
diff --git a/hicn-plugin/src/faces/app/face_cons.c b/hicn-plugin/src/faces/app/face_cons.c
index e51201c21..d44ba1a2b 100644
--- a/hicn-plugin/src/faces/app/face_cons.c
+++ b/hicn-plugin/src/faces/app/face_cons.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -57,10 +57,12 @@ hicn_face_cons_add (ip4_address_t * nh_addr4, ip6_address_t * nh_addr6,
ip46_address_t nh_addr = to_ip46 (0, (u8 *) nh_addr4);
- hicn_iface_ip_add (&if_ip, &nh_addr, swif, faceid1);
+ index_t adj_index = adj_nbr_find(FIB_PROTOCOL_IP4, VNET_LINK_IP4, &nh_addr, swif);
+
+ hicn_iface_add (&nh_addr, swif, faceid1, DPO_PROTO_IP4, adj_index);
hicn_face_t *face = hicn_dpoi_get_from_idx (*faceid1);
- face->shared.flags |= HICN_FACE_FLAGS_APPFACE_CONS;
+ face->flags |= HICN_FACE_FLAGS_APPFACE_CONS;
get_two_ip6_addresses (&(if_ip.ip6), nh_addr6);
ip6_add_del_interface_address (vm,
@@ -68,10 +70,12 @@ hicn_face_cons_add (ip4_address_t * nh_addr4, ip6_address_t * nh_addr6,
&(if_ip.ip6),
ADDR_MGR_IP6_CONS_LEN, 0 /* is_del */ );
- hicn_iface_ip_add (&if_ip, (ip46_address_t *) nh_addr6, swif, faceid2);
+ adj_index = adj_nbr_find(FIB_PROTOCOL_IP6, VNET_LINK_IP6, &nh_addr, swif);
+
+ hicn_iface_add ((ip46_address_t *) nh_addr6, swif, faceid2, DPO_PROTO_IP6, adj_index);
face = hicn_dpoi_get_from_idx (*faceid2);
- face->shared.flags |= HICN_FACE_FLAGS_APPFACE_CONS;
+ face->flags |= HICN_FACE_FLAGS_APPFACE_CONS;
return HICN_ERROR_NONE;
}
@@ -84,9 +88,9 @@ hicn_face_cons_del (hicn_face_id_t face_id)
hicn_face_t *face = hicn_dpoi_get_from_idx (face_id);
- if (face->shared.flags & HICN_FACE_FLAGS_APPFACE_CONS)
+ if (face->flags & HICN_FACE_FLAGS_APPFACE_CONS)
{
- return hicn_face_ip_del (face_id);
+ return hicn_face_del (face_id);
}
else
{
diff --git a/hicn-plugin/src/faces/app/face_prod.c b/hicn-plugin/src/faces/app/face_prod.c
index ae59719ce..645154325 100644
--- a/hicn-plugin/src/faces/app/face_prod.c
+++ b/hicn-plugin/src/faces/app/face_prod.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -98,10 +98,11 @@ hicn_app_state_del (u32 swif)
);
/* *INDENT-ON* */
- prefix = &(face_state_vec[swif].prefix);
if (!found)
return HICN_ERROR_APPFACE_NOT_FOUND;
+ prefix = &(face_state_vec[swif].prefix);
+
int ret = HICN_ERROR_NONE;
if (ip46_address_is_ip4 (&prefix->fp_addr))
{
@@ -132,7 +133,7 @@ hicn_face_prod_add (fib_prefix_t * prefix, u32 sw_if, u32 * cs_reserved,
hicn_main_t *hm = &hicn_main;
ip46_address_t local_app_ip;
- ip46_address_t remote_app_ip;
+ CLIB_UNUSED(ip46_address_t remote_app_ip);
u32 if_flags = 0;
if (!hm->is_enabled)
@@ -160,28 +161,20 @@ hicn_face_prod_add (fib_prefix_t * prefix, u32 sw_if, u32 * cs_reserved,
{
return HICN_ERROR_APPFACE_PROD_PREFIX_NULL;
}
+
+ u8 isv6 = ip46_address_is_ip4(prod_addr);
+ index_t adj_index = adj_nbr_find(isv6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4, isv6 ? VNET_LINK_IP6 : VNET_LINK_IP4, prod_addr, sw_if);
+
/*
* Check if a producer face is already existing for the same prefix
* and sw_if
*/
- if (ip46_address_is_ip4 (&prefix->fp_addr))
- {
- face =
- hicn_face_ip4_get (&(prefix->fp_addr.ip4), sw_if,
- &hicn_face_ip_remote_hashtb);
- }
- else
- {
- face =
- hicn_face_ip6_get (&(prefix->fp_addr.ip6), sw_if,
- &hicn_face_ip_remote_hashtb);
- if (face != NULL)
- return HICN_ERROR_FACE_ALREADY_CREATED;
- }
+ face = hicn_face_get (&(prefix->fp_addr), sw_if,
+ &hicn_face_hashtb, adj_index);
if (face != NULL)
{
- if (!(face->shared.flags & HICN_FACE_FLAGS_DELETED))
+ if (!(face->flags & HICN_FACE_FLAGS_DELETED))
return HICN_ERROR_FACE_ALREADY_CREATED;
/*
@@ -189,19 +182,17 @@ hicn_face_prod_add (fib_prefix_t * prefix, u32 sw_if, u32 * cs_reserved,
* producer's prefix.
*/
/* It should never happens, this is a safety check. */
- if (face->shared.flags & HICN_FACE_FLAGS_APPFACE_CONS)
+ if (face->flags & HICN_FACE_FLAGS_APPFACE_CONS)
return HICN_ERROR_FACE_ALREADY_CREATED;
/* If the face exists but is marked as deleted, undelete it */
- if (face->shared.flags & HICN_FACE_FLAGS_DELETED)
+ if (face->flags & HICN_FACE_FLAGS_DELETED)
{
/*
* remove the deleted flag and retrieve the face
* local addr
*/
- face->shared.flags &= HICN_FACE_FLAGS_DELETED;
- hicn_face_prod_t *prod_face = (hicn_face_prod_t *) face->data;
- local_app_ip = prod_face->ip_face.local_addr;
+ face->flags &= HICN_FACE_FLAGS_DELETED;
}
}
else
@@ -222,9 +213,7 @@ hicn_face_prod_add (fib_prefix_t * prefix, u32 sw_if, u32 * cs_reserved,
local_app_ip = to_ip46 ( /* isv6 */ 0, local_app_ip4.as_u8);
remote_app_ip = to_ip46 ( /* isv6 */ 0, remote_app_ip4.as_u8);
- ret =
- hicn_face_ip_add (&local_app_ip, &remote_app_ip, sw_if, faceid,
- HICN_FACE_FLAGS_APPFACE_PROD);
+ vnet_build_rewrite_for_sw_interface(vnm, sw_if, VNET_LINK_IP4, &remote_app_ip4);
}
else
{
@@ -242,41 +231,29 @@ hicn_face_prod_add (fib_prefix_t * prefix, u32 sw_if, u32 * cs_reserved,
0 /* is_del */ );
local_app_ip = to_ip46 ( /* isv6 */ 1, local_app_ip6.as_u8);
remote_app_ip = to_ip46 ( /* isv6 */ 1, remote_app_ip6.as_u8);
-
- ret =
- hicn_face_ip_add (&local_app_ip, &remote_app_ip, sw_if, faceid,
- HICN_FACE_FLAGS_APPFACE_PROD);
}
-
- face = hicn_dpoi_get_from_idx (*faceid);
-
- face->shared.flags |= HICN_FACE_FLAGS_APPFACE_PROD;
-
- hicn_face_prod_t *prod_face = (hicn_face_prod_t *) face->data;
-
- /*
- * For the moment we keep them here although it would be good
- * to create a different face for appface
- */
- prod_face->policy_vft.hicn_cs_insert = hicn_cs_lru.hicn_cs_insert;
- prod_face->policy_vft.hicn_cs_update = hicn_cs_lru.hicn_cs_update;
- prod_face->policy_vft.hicn_cs_dequeue = hicn_cs_lru.hicn_cs_dequeue;
- prod_face->policy_vft.hicn_cs_delete_get =
- hicn_cs_lru.hicn_cs_delete_get;
- prod_face->policy_vft.hicn_cs_trim = hicn_cs_lru.hicn_cs_trim;
- prod_face->policy_vft.hicn_cs_flush = hicn_cs_lru.hicn_cs_flush;
-
}
- if (ret == HICN_ERROR_NONE
- && hicn_face_prod_set_lru_max (*faceid, cs_reserved) == HICN_ERROR_NONE)
+ if (ret == HICN_ERROR_NONE)
+ // && hicn_face_prod_set_lru_max (*faceid, cs_reserved) == HICN_ERROR_NONE)
{
+ fib_route_path_t rpath = {0};
+ fib_route_path_t * rpaths = NULL;
+
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;
+
+ rpath.frp_weight = 1;
+ rpath.frp_sw_if_index = ~0;
+ rpath.frp_addr.ip4.as_u32 = remote_app_ip.ip4.as_u32;
+ rpath.frp_sw_if_index = sw_if;
+ rpath.frp_proto = DPO_PROTO_IP4;
+
+ vec_add1 (rpaths, rpath);
}
else
{
@@ -287,21 +264,42 @@ hicn_face_prod_add (fib_prefix_t * prefix, u32 sw_if, u32 * cs_reserved,
prefix->fp_addr.ip6.as_u64[1] =
prefix->fp_addr.ip6.as_u64[1] & mask.as_u64[1];
prefix->fp_proto = FIB_PROTOCOL_IP6;
+
+ rpath.frp_weight = 1;
+ rpath.frp_sw_if_index = ~0;
+ rpath.frp_addr.ip6.as_u64[0] = remote_app_ip.ip6.as_u64[0];
+ rpath.frp_addr.ip6.as_u64[1] = remote_app_ip.ip6.as_u64[1];
+ rpath.frp_sw_if_index = sw_if;
+ rpath.frp_proto = DPO_PROTO_IP6;
+
+ vec_add1 (rpaths, rpath);
}
+ u32 fib_index = fib_table_find (prefix->fp_proto, 0);
+ fib_table_entry_path_add2 (fib_index,
+ prefix,
+ FIB_SOURCE_CLI,
+ FIB_ENTRY_FLAG_NONE, rpaths);
+
+ hicn_route_enable(prefix);
hicn_app_state_create (sw_if, prefix);
- ret = hicn_route_add (faceid, 1, prefix);
}
+ adj_index = adj_nbr_find(isv6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4, isv6 ? VNET_LINK_IP6 : VNET_LINK_IP4, prod_addr, sw_if);
+ face = hicn_face_get(&local_app_ip, sw_if, &hicn_face_hashtb, adj_index);//HICN_FACE_FLAGS_APPFACE_PROD);
+
+ *faceid = hicn_dpoi_get_index (face);
+
+ face->flags |= HICN_FACE_FLAGS_APPFACE_PROD;
+
+ hicn_face_unlock_with_id(*faceid);
+
*prod_addr = local_app_ip;
/* Cleanup in case of something went wrong. */
if (ret)
{
hicn_app_state_del (sw_if);
-
- if (*faceid != HICN_FACE_NULL)
- hicn_face_ip_del (*faceid);
}
return ret;
}
@@ -314,88 +312,33 @@ hicn_face_prod_del (hicn_face_id_t face_id)
hicn_face_t *face = hicn_dpoi_get_from_idx (face_id);
- if (face->shared.flags & HICN_FACE_FLAGS_APPFACE_PROD)
+ if (face->flags & HICN_FACE_FLAGS_APPFACE_PROD)
{
- hicn_face_prod_t *prod_face = (hicn_face_prod_t *) face->data;
- /* Free the CS reserved for the face */
- hicn_main.pitcs.pcs_app_count -= prod_face->policy.max;
- prod_face->policy.max = 0;
-
/* Remove the face from the fib */
- hicn_route_del_nhop (&(face_state_vec[face->shared.sw_if].prefix),
- face_id);
+ hicn_route_disable(&(face_state_vec[face->sw_if].prefix));
+ //hicn_route_del_nhop (&(face_state_vec[face->sw_if].prefix),
+ // face_id);
- /*
- * Delete the content in the CS before deleting the face.
- * Mandatory to prevent hitting the CS and not having the lru list
- * due to a early deletion of the face.
- */
- vlib_main_t *vm = vlib_get_main ();
- prod_face->policy_vft.hicn_cs_flush (vm, &(hicn_main.pitcs),
- &(prod_face->policy));
-
- int ret = hicn_face_ip_del (face_id);
- return ret ==
- HICN_ERROR_NONE ? hicn_app_state_del (face->shared.sw_if) : ret;
+ //int ret = hicn_face_del (face_id);
+ return hicn_app_state_del (face->sw_if);
+ //ret == HICN_ERROR_NONE ? hicn_app_state_del (face->sw_if) : ret;
}
else
{
return HICN_ERROR_APPFACE_NOT_FOUND;
}
-}
-
-int
-hicn_face_prod_set_lru_max (hicn_face_id_t face_id, u32 * requested_size)
-{
- int ret = HICN_ERROR_NONE;
- vlib_main_t *vm = vlib_get_main ();
- hicn_face_t *face;
- hicn_face_prod_t *face_prod;
-
- if (!hicn_infra_fwdr_initialized)
- {
- ret = HICN_ERROR_FWD_NOT_ENABLED;
- vlib_cli_output (vm, "hicn: %s\n", get_error_string (ret));
- return ret;
- }
- face = hicn_dpoi_get_from_idx (face_id);
- face_prod = (hicn_face_prod_t *) face->data;
-
- if (face == NULL)
- return HICN_ERROR_FACE_NOT_FOUND;
-
- if (*requested_size > HICN_PARAM_FACE_MAX_CS_RESERVED)
- *requested_size = HICN_PARAM_FACE_MAX_CS_RESERVED;
- uint32_t available =
- hicn_main.pitcs.pcs_app_max - hicn_main.pitcs.pcs_app_count;
-
- if (*requested_size > available)
- *requested_size = available;
-
- face_prod->policy.max = *requested_size;
- face_prod->policy.count = 0;
- face_prod->policy.head = face_prod->policy.tail = 0;
-
- hicn_main.pitcs.pcs_app_count += *requested_size;
-
- return ret;
+ return HICN_ERROR_NONE;
}
u8 *
format_hicn_face_prod (u8 * s, va_list * args)
{
- index_t index = va_arg (*args, index_t);
+ CLIB_UNUSED (index_t index) = va_arg (*args, index_t);
CLIB_UNUSED (u32 indent) = va_arg (*args, u32);
- hicn_face_t *face;
- hicn_face_prod_t *prod_face;
-
- face = hicn_dpoi_get_from_idx (index);
- prod_face = (hicn_face_prod_t *) face->data;
s =
- format (s, " (producer face: CS size %d, data cached %d)",
- prod_face->policy.max, prod_face->policy.count);
+ format (s, " (producer)");
return s;
}
diff --git a/hicn-plugin/src/faces/app/face_prod.h b/hicn-plugin/src/faces/app/face_prod.h
index 33e2a4199..4cb2e3fbf 100644
--- a/hicn-plugin/src/faces/app/face_prod.h
+++ b/hicn-plugin/src/faces/app/face_prod.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -17,7 +17,7 @@
#define _FACE_PRODUCER_H_
#include "../../cache_policies/cs_policy.h"
-#include "../ip/face_ip.h"
+#include "../face.h"
/**
* @file
@@ -56,15 +56,6 @@ extern hicn_face_prod_state_t *face_state_vec;
#define DEFAULT_PROBING_PORT 3784
-typedef struct __attribute__ ((packed)) hicn_face_prod_t_
-{
- hicn_face_ip_t ip_face;
-
- hicn_cs_policy_t policy;
- hicn_cs_policy_vft_t policy_vft;
-
-} hicn_face_prod_t;
-
/**
* @brief Add a new producer application face
*
diff --git a/hicn-plugin/src/faces/app/face_prod_node.c b/hicn-plugin/src/faces/app/face_prod_node.c
index 0ef25fe94..80c3e124c 100644
--- a/hicn-plugin/src/faces/app/face_prod_node.c
+++ b/hicn-plugin/src/faces/app/face_prod_node.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -300,8 +300,8 @@ VLIB_REGISTER_NODE(hicn_face_prod_input_node) =
.n_next_nodes = HICN_FACE_PROD_N_NEXT,
.next_nodes =
{
- [HICN_FACE_PROD_NEXT_DATA_IP4] = "hicn-face-ip4-input",
- [HICN_FACE_PROD_NEXT_DATA_IP6] = "hicn-face-ip6-input",
+ [HICN_FACE_PROD_NEXT_DATA_IP4] = "hicn4-face-input",
+ [HICN_FACE_PROD_NEXT_DATA_IP6] = "hicn6-face-input",
[HICN_FACE_PROD_NEXT_ERROR_DROP] = "error-drop",
},
};
diff --git a/hicn-plugin/src/faces/face.c b/hicn-plugin/src/faces/face.c
index f2dcdd151..1abbf8887 100644
--- a/hicn-plugin/src/faces/face.c
+++ b/hicn-plugin/src/faces/face.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -12,16 +12,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include <vnet/fib/fib_entry_track.h>
#include "face.h"
-#include "ip/face_ip.h"
-#include "ip/face_ip_node.h"
-#include "ip/iface_ip_node.h"
-#include "ip/dpo_ip.h"
-#include "udp/face_udp.h"
-#include "udp/face_udp_node.h"
-#include "udp/iface_udp_node.h"
-#include "udp/dpo_udp.h"
+#include "../hicn.h"
+#include "../params.h"
+#include "../error.h"
+#include "../mapme.h"
+#include "../mapme_eventmgr.h"
dpo_id_t *face_dpo_vec;
hicn_face_vft_t *face_vft_vec;
@@ -33,6 +31,10 @@ dpo_type_t first_type = DPO_FIRST;
vlib_combined_counter_main_t *counters;
+dpo_type_t hicn_face_type;
+
+fib_node_type_t hicn_face_fib_node_type;
+
const char *HICN_FACE_CTRX_STRING[] = {
#define _(a,b,c) c,
foreach_hicn_face_counter
@@ -56,40 +58,189 @@ face_show (u8 * s, int face_id, u32 indent)
}
-void
-register_face_type (hicn_face_type_t face_type, hicn_face_vft_t * vft,
- char *name)
+mhash_t hicn_face_vec_hashtb;
+mhash_t hicn_face_hashtb;
+
+hicn_face_vec_t * hicn_vec_pool;
+
+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,
+};
+
+
+const static char *const *const hicn_face_nodes[DPO_PROTO_NUM] =
+{
+ [DPO_PROTO_IP4] = hicn_face4_nodes,
+ [DPO_PROTO_IP6] = hicn_face6_nodes
+};
+
+const static dpo_vft_t hicn_face_dpo_vft =
+{
+ .dv_lock = hicn_face_lock,
+ .dv_unlock = hicn_face_unlock,
+ .dv_format = format_hicn_face,
+};
+
+static fib_node_t *
+hicn_face_node_get (fib_node_index_t index)
{
- if (first_type == DPO_FIRST)
- first_type = face_type;
-
- int idx = face_type - first_type;
- ASSERT (idx >= 0);
- vec_validate (face_vft_vec, idx);
- vec_validate (face_type_names_vec, idx);
-
- /* Copy the null char as well */
- char *name_str = (char *) malloc ((strlen (name) + 1) * sizeof (char));
- strcpy (name_str, name);
- face_vft_vec[idx] = *vft;
- face_type_names_vec[idx] = name_str;
+ hicn_face_t * face;
+
+ face = hicn_dpoi_get_from_idx(index);
+
+ return (&face->fib_node);
+}
+
+static void
+hicn_face_last_lock_gone (fib_node_t *node)
+{
+}
+
+static hicn_face_t *
+hicn_face_from_fib_node (fib_node_t * node)
+{
+ return ((hicn_face_t *) (((char *) node) -
+ STRUCT_OFFSET_OF (hicn_face_t, fib_node)));
+}
+
+static fib_node_back_walk_rc_t
+hicn_face_back_walk_notify (fib_node_t *node,
+ fib_node_back_walk_ctx_t *ctx)
+{
+
+ hicn_face_t *face = hicn_face_from_fib_node (node);
+
+ const dpo_id_t * dpo_loadbalance = fib_entry_contribute_ip_forwarding (face->fib_entry_index);
+ const load_balance_t *lb0 = load_balance_get(dpo_loadbalance->dpoi_index);
+
+ const dpo_id_t *dpo = load_balance_get_bucket_i(lb0,0);
+
+ dpo_stack(hicn_face_type, face->dpo.dpoi_proto, &face->dpo, dpo);
+ /* if (dpo_is_adj(dpo)) */
+ /* { */
+ /* ip_adjacency_t * adj = adj_get (dpo->dpoi_index); */
+
+ /* if (dpo->dpoi_type == DPO_ADJACENCY_MIDCHAIN || */
+ /* dpo->dpoi_type == DPO_ADJACENCY_MCAST_MIDCHAIN) */
+ /* { */
+ /* adj_nbr_midchain_stack(dpo->dpoi_index, &face->dpo); */
+ /* } */
+ /* else */
+ /* { */
+ /* dpo_stack(hicn_face_type, face->dpo.dpoi_proto, &face->dpo, dpo); */
+ /* } */
+ /* } */
+
+ return (FIB_NODE_BACK_WALK_CONTINUE);
}
+static void
+hicn_face_show_memory (void)
+{
+}
+
+
+static const fib_node_vft_t hicn_face_fib_node_vft =
+ {
+ .fnv_get = hicn_face_node_get,
+ .fnv_last_lock = hicn_face_last_lock_gone,
+ .fnv_back_walk = hicn_face_back_walk_notify,
+ .fnv_mem_show = hicn_face_show_memory,
+ };
+
// Make this more flexible for future types face
void
hicn_face_module_init (vlib_main_t * vm)
{
pool_validate (hicn_dpoi_face_pool);
pool_alloc (hicn_dpoi_face_pool, 1024);
- hicn_face_ip_init (vm);
- hicn_iface_ip_init (vm);
- hicn_face_udp_init (vm);
- hicn_iface_udp_init (vm);
counters =
vec_new (vlib_combined_counter_main_t,
HICN_PARAM_FACES_MAX * HICN_N_COUNTER);
+
+ mhash_init (&hicn_face_vec_hashtb,
+ sizeof (hicn_face_input_faces_t) /* value */ ,
+ sizeof (hicn_face_key_t) /* key */ );
+ mhash_init (&hicn_face_hashtb,
+ sizeof (hicn_face_id_t) /* value */ ,
+ sizeof (hicn_face_key_t) /* key */ );
+
+ pool_alloc(hicn_vec_pool, 100);
+
+ /*
+ * How much useful is the following registration?
+ * So far it seems that we need it only for setting the dpo_type.
+ */
+ hicn_face_type =
+ dpo_register_new_type (&hicn_face_dpo_vft, hicn_face_nodes);
+
+ /*
+ * We register a new node type to get informed when the adjacency corresponding
+ * to a face is updated
+ */
+ hicn_face_fib_node_type = fib_node_register_new_type(&hicn_face_fib_node_vft);
+}
+
+u8 *
+format_hicn_face (u8 * s, va_list * args)
+{
+ index_t index = va_arg (*args, index_t);
+ u32 indent = va_arg (*args, u32);
+ hicn_face_t *face;
+
+ face = hicn_dpoi_get_from_idx (index);
+
+ if (face->flags & HICN_FACE_FLAGS_FACE)
+ {
+ hicn_face_id_t face_id = hicn_dpoi_get_index (face);
+ s = format (s, "%U Face %d: ", format_white_space, indent, face_id);
+ s = format (s, "nat address %U locks %u, path_label %u",
+ format_ip46_address, &face->nat_addr, IP46_TYPE_ANY,
+ face->locks, face->pl_id);
+
+ if ((face->flags & HICN_FACE_FLAGS_APPFACE_PROD))
+ s = format (s, " (producer)");
+ else if ((face->flags & HICN_FACE_FLAGS_APPFACE_CONS))
+ s = format (s, " (consumer)");
+
+ if ((face->flags & HICN_FACE_FLAGS_DELETED))
+ s = format (s, " (deleted)");
+
+ s = format (s, "\n%U%U",
+ format_white_space, indent + 2,
+ format_dpo_id, &face->dpo, indent + 3);
+ }
+ else
+ {
+ hicn_face_id_t face_id = hicn_dpoi_get_index (face);
+ s = format (s, "%U iFace %d: ", format_white_space, indent, face_id);
+ s = format (s, "nat address %U locks %u, path_label %u",
+ format_ip46_address, &face->nat_addr, IP46_TYPE_ANY,
+ face->locks, face->pl_id);
+
+ if ((face->flags & HICN_FACE_FLAGS_APPFACE_PROD))
+ s = format (s, " (producer)");
+ else if ((face->flags & HICN_FACE_FLAGS_APPFACE_CONS))
+ s = format (s, " (consumer)");
+
+ if ((face->flags & HICN_FACE_FLAGS_DELETED))
+ s = format (s, " (deleted)");
+ }
+
+ return s;
}
+
u8 *
format_hicn_face_all (u8 * s, int n, ...)
{
@@ -104,46 +255,226 @@ format_hicn_face_all (u8 * s, int n, ...)
/* *INDENT-OFF* */
pool_foreach ( face, hicn_dpoi_face_pool,
{
- hicn_face_vft_t * vft = hicn_face_get_vft(face->shared.face_type);
- hicn_face_id_t face_id = hicn_dpoi_get_index(face);
- s = format(s, "%U\n", vft->format_face, face_id, indent);
+ s = format(s, "%U\n", format_hicn_face, hicn_dpoi_get_index(face), indent);
});
/* *INDENT-ON* */
return s;
}
-hicn_face_vft_t *
-hicn_face_get_vft (hicn_face_type_t face_type)
-{
- int idx = face_type - first_type;
- if (idx >= 0)
- return &face_vft_vec[idx];
- else
- return NULL;
-
-}
-
int
hicn_face_del (hicn_face_id_t face_id)
{
+ hicn_face_t *face = hicn_dpoi_get_from_idx (face_id);
+ hicn_face_key_t key;
+ hicn_face_key_t old_key;
+ hicn_face_key_t old_key2;
+
+ hicn_face_get_key (&(face->nat_addr), face->sw_if, &(face->dpo),
+ &key);
+ hicn_face_input_faces_t *in_faces_vec =
+ hicn_face_get_vec (&(face->nat_addr),
+ &hicn_face_vec_hashtb);
+ if (in_faces_vec != NULL)
+ {
+ hicn_face_vec_t *vec =
+ pool_elt_at_index (hicn_vec_pool, in_faces_vec->vec_id);
+ u32 index_face = vec_search (*vec, face_id);
+ vec_del1 (*vec, index_face);
+
+ if (vec_len (*vec) == 0)
+ {
+ pool_put_index (hicn_vec_pool, in_faces_vec->vec_id);
+ mhash_unset (&hicn_face_vec_hashtb, &key,
+ (uword *) & old_key);
+ vec_free (*vec);
+ }
+ else
+ {
+ /* Check if the face we are deleting is the preferred one. */
+ /* If so, repleace with another. */
+ if (in_faces_vec->face_id == face_id)
+ {
+ in_faces_vec->face_id = (*vec)[0];
+ }
+ }
+
+ mhash_unset (&hicn_face_hashtb, &key,
+ (uword *) & old_key2);
+ }
+
int ret = HICN_ERROR_NONE;
if (hicn_dpoi_idx_is_valid (face_id))
{
hicn_face_t *face = hicn_dpoi_get_from_idx (face_id);
- face->shared.locks--;
- if (face->shared.locks == 0)
+ face->locks--;
+ if (face->locks == 0)
pool_put_index (hicn_dpoi_face_pool, face_id);
else
- face->shared.flags |= HICN_FACE_FLAGS_DELETED;
+ face->flags |= HICN_FACE_FLAGS_DELETED;
}
else
ret = HICN_ERROR_FACE_NOT_FOUND;
+
return ret;
}
+static void
+hicn_iface_to_face(hicn_face_t *face, const dpo_id_t * dpo)
+{
+ dpo_stack(hicn_face_type, dpo->dpoi_proto, &face->dpo, dpo);
+
+ face->flags &= ~HICN_FACE_FLAGS_IFACE;
+ face->flags |= HICN_FACE_FLAGS_FACE;
+
+ if (dpo_is_adj(dpo))
+ {
+ fib_node_init (&face->fib_node, hicn_face_fib_node_type);
+ fib_node_lock (&face->fib_node);
+
+ if (dpo->dpoi_type != DPO_ADJACENCY_MIDCHAIN ||
+ dpo->dpoi_type != DPO_ADJACENCY_MCAST_MIDCHAIN)
+ {
+ ip_adjacency_t * adj = adj_get (dpo->dpoi_index);
+ ip46_address_t * nh = &(adj->sub_type.nbr.next_hop);
+ fib_prefix_t prefix;
+
+ if (!ip46_address_is_zero(nh))
+ {
+ fib_prefix_from_ip46_addr(nh, &prefix);
+
+ u32 fib_index = fib_table_find(prefix.fp_proto, HICN_FIB_TABLE);
+
+ face->fib_entry_index = fib_entry_track (fib_index,
+ &prefix,
+ hicn_face_fib_node_type,
+ hicn_dpoi_get_index(face), &face->fib_sibling);
+ }
+ }
+ }
+}
+
+/*
+ * Utility that adds a new face cache entry. For the moment we assume that
+ * the ip_adjacency has already been set up.
+ */
+int
+hicn_face_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_flags_t flags = (hicn_face_flags_t) 0;
+ flags |= HICN_FACE_FLAGS_FACE;
+
+ hicn_face_t *face;
+
+ face =
+ hicn_face_get_with_dpo (nat_address, sw_if, dpo_nh,
+ &hicn_face_hashtb);
+
+ if (face != NULL)
+ {
+ *pfaceid = hicn_dpoi_get_index (face);
+ return HICN_ERROR_FACE_ALREADY_CREATED;
+ }
+
+ face =
+ hicn_face_get (nat_address, sw_if,
+ &hicn_face_hashtb, dpo_nh->dpoi_index);
+
+ dpo_id_t temp_dpo = DPO_INVALID;
+ temp_dpo.dpoi_index = dpo_nh->dpoi_index;
+ hicn_face_key_t key;
+ hicn_face_get_key (nat_address, sw_if, dpo_nh, &key);
+
+ if (face == NULL)
+ {
+
+ hicn_iface_add (nat_address, sw_if, pfaceid, dpo_nh->dpoi_proto, dpo_nh->dpoi_index);
+ face = hicn_dpoi_get_from_idx (*pfaceid);
+
+ mhash_set_mem (&hicn_face_hashtb, &key, (uword *) pfaceid,
+ 0);
+
+ hicn_face_get_key (nat_address, sw_if, &temp_dpo, &key);
+ mhash_set_mem (&hicn_face_hashtb, &key, (uword *) pfaceid,
+ 0);
+ }
+ else
+ {
+ /* We found an iface and we convert it to a face */
+ *pfaceid = hicn_dpoi_get_index (face);
+ mhash_set_mem (&hicn_face_hashtb, &key, (uword *) pfaceid,
+ 0);
+ }
+
+ hicn_iface_to_face(face, dpo_nh);
+
+ temp_dpo.dpoi_index = ~0;
+
+ hicn_face_input_faces_t *in_faces =
+ hicn_face_get_vec (nat_address, &hicn_face_vec_hashtb);
+
+ if (in_faces == NULL)
+ {
+ hicn_face_input_faces_t in_faces_temp;
+ hicn_face_vec_t *vec;
+ pool_get (hicn_vec_pool, vec);
+ *vec = vec_new (hicn_face_vec_t, 0);
+ u32 index = vec - hicn_vec_pool;
+ in_faces_temp.vec_id = index;
+ vec_add1 (*vec, *pfaceid);
+
+ in_faces_temp.face_id = *pfaceid;
+
+ hicn_face_get_key (nat_address, 0, &temp_dpo, &key);
+
+ mhash_set_mem (&hicn_face_vec_hashtb, &key,
+ (uword *) & in_faces_temp, 0);
+ }
+ else
+ {
+ hicn_face_vec_t *vec =
+ pool_elt_at_index (hicn_vec_pool, in_faces->vec_id);
+
+ /* */
+ if (vec_search (*vec, *pfaceid) != ~0)
+ return HICN_ERROR_FACE_ALREADY_CREATED;
+
+ vec_add1 (*vec, *pfaceid);
+
+ hicn_iface_to_face(face, dpo_nh);
+
+ hicn_face_get_key (nat_address, 0, &temp_dpo, &key);
+
+ mhash_set_mem (&hicn_face_vec_hashtb, &key, (uword *) in_faces,
+ 0);
+
+ /* If the face is an application producer face, we set it as the preferred incoming face. */
+ /* This is required to handle the CS separation, and the push api in a lightway */
+ if (is_app_prod)
+ {
+ in_faces->face_id = *pfaceid;
+ }
+ }
+
+ retx_t *retx = vlib_process_signal_event_data (vlib_get_main (),
+ hicn_mapme_eventmgr_process_node.index,
+ HICN_MAPME_EVENT_FACE_ADD, 1,
+ sizeof (retx_t));
+
+ /* *INDENT-OFF* */
+ *retx = (retx_t) {
+ .face_id = *pfaceid,
+ };
+ /* *INDENT-ON* */
+
+ return HICN_ERROR_NONE;
+}
+
+
/*
* fd.io coding-style-patch-verification: ON
*
diff --git a/hicn-plugin/src/faces/face.h b/hicn-plugin/src/faces/face.h
index b758ece06..234c3fcc2 100644
--- a/hicn-plugin/src/faces/face.h
+++ b/hicn-plugin/src/faces/face.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -16,35 +16,66 @@
#ifndef __HICN_FACE_H__
#define __HICN_FACE_H__
+#include <vnet/fib/fib_node.h>
#include <vnet/vnet.h>
#include <vlib/vlib.h>
+#include <vnet/ip/ip46_address.h>
#include <vnet/dpo/dpo.h>
#include <vnet/adj/adj_types.h>
-#include "../hicn.h"
+#include <vppinfra/bihash_8_8.h>
+#include <vnet/adj/adj_midchain.h>
+
+#include "../error.h"
typedef u8 hicn_face_flags_t;
typedef index_t hicn_face_id_t;
-typedef dpo_type_t hicn_face_type_t;
/**
- * @file
+ * @file face.h
+ *
+ * This file implements a general face type. The purpose of a face is to
+ * carry the needed information to forward interest and data packets to the
+ * next node in the network. There are two type of faces: complete faces (in short
+ * faces), and incomplete faces (in short ifaces).
*
- * @brief Face
+ * A face that does not contain the indication of the adjacency is an
+ * incomplete face (iface), otherwise it is considered to be complete. Ifaces are
+ * used to forward data back to the previous hICN hop from which we received an
+ * interest, while faces are used to forward interest packets to the next hicn node.
+ * Faces and ifaces are created at two different points in time. Faces are created
+ * when a route is added, while ifaces are created when an interest is received.
+ * In details, faces and ifaces carry the following information:
+ * - nat_addr: the ip address to perform src nat or dst nat on interest and data packets, respectively;
+ * - pl_id: the path label
+ * - locks: the number of entities using this face. When 0 the face can be deallocated
+ * - dpo: the dpo that identifies the next node in the vlib graph for processing the vlib
+ * buffer. The dpo contains the dpo.dpoi_next field that points to the next node
+ * in the vlib graph and the dpo.dpoi_index which is an index to adj used by the next node
+ * to perform the l2 rewrite. In case of ifaces, it is likely we don't know the
+ * adjacency when creting the face. In this case, the next node in the vlib graph
+ * will be the node that performs a lookup in the fib. Only in case of udp tunnels,
+ * which are bidirectional tunnel we know that the incoming tunnel is also the outgoing
+ * one, therefore in this case we store the tunnel in the dpo.dpoi_index fields. For
+ * all the other tunnels (which are most likely unidirectional), the source address of
+ * the interest will be used to retrieve the outgoing tunnel when sending the corresponding
+ * data back.
+ * - sw_if: the incoming interface of the interest
+ * - fib_node, fib_entry_index and fib_sibling are information used to be notified of
+ * changes in the adjacency pointed by the dpo.
*
- * This file implements a general face type. A face is carried through nodes as a
- * dpo. The face state (hicn_face_t) is the object pointed by the
- * dpoi_index in the dpo_id_t (see
- * https://docs.fd.io/vpp/18.07/d0/d37/dpo_8h_source.html).
- * A face state that does not contain the indication of the l2 adjacency is an
- * incomplete face (iface), otherwise it is considered to be complete. Each face type
- * provide specific node for processing packets in input or output of complete
- * and incomplete faces.
+ * We maintain two hash tables to retrieve faces and ifaces. In particular one hash table which
+ * index faces and ifaces for nat_address, sw_if and dpo. This is used to retrieve existing faces
+ * or ifaces when an interest is received and when an new face is created. A second hash table that
+ * indexes vectors of faces for nat_address and sw_if. This is used to retrieve a list of possible
+ * incoming faces when a data is received.
*/
/**
- * @brief Fields shared among all the different types of faces
+ * @brief Structure representing a face. It containes the fields shared among
+ * all the types of faces as well it leaves some space for storing additional
+ * information specific to each type.
*/
-typedef struct __attribute__ ((packed)) hicn_face_shared_s
+typedef struct __attribute__ ((packed)) hicn_face_s
{
/* Flags to idenfity if the face is incomplete (iface), complete (face) */
/* And a network or application face (1B) */
@@ -59,34 +90,24 @@ typedef struct __attribute__ ((packed)) hicn_face_shared_s
/* Number of dpo holding a reference to the dpoi (4B) */
u32 locks;
- /* Adjacency for the neighbor (4B) */
- adj_index_t adj;
+ /* Dpo for the adjacency (8B) */
+ union {
+ dpo_id_t dpo;
+ u64 align_dpo;
+ };
+
+ /* Local address of the interface sw_if */
+ ip46_address_t nat_addr;
/* local interface for the local ip address */
u32 sw_if;
- /* Face id corresponding to the global face pool (4B) */
- union
- {
- hicn_face_type_t face_type;
- u32 int_face_type; //To force the face_type_t to be 4B
- };
+ fib_node_t fib_node;
-} hicn_face_shared_t;
+ fib_node_index_t fib_entry_index;
-/**
- * @brief Structure holding the face state. It containes the fields shared among
- * all the types of faces as well it leaves some space for storing additional
- * information specific to each type.
- */
-typedef struct __attribute__ ((packed)) hicn_face_s
-{
- /* Additional space to fill with face_type specific information */
- u8 data[2 * CLIB_CACHE_LINE_BYTES - sizeof (hicn_face_shared_t)];
- hicn_face_shared_t shared;
-}
-
-hicn_face_t;
+ u32 fib_sibling;
+} hicn_face_t;
/* Pool of faces */
extern hicn_face_t *hicn_dpoi_face_pool;
@@ -107,6 +128,10 @@ extern hicn_face_t *hicn_dpoi_face_pool;
#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_FACE_IS_APP 0x01
+
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");
@@ -127,11 +152,6 @@ STATIC_ASSERT ((HICN_FACE_FLAGS_APPFACE_CONS >>
/**
* @brief Definition of the virtual functin table for an hICN FACE DPO.
- *
- * An hICN dpo is a combination of a dpo context (hicn_dpo_ctx or struct that
- * extends a hicn_dpo_ctx) and a strategy node. The following virtual function table
- * template that glues together the fuction to interact with the context and the
- * creating the dpo
*/
typedef struct hicn_face_vft_s
{
@@ -155,6 +175,8 @@ typedef enum
HICN_N_COUNTER
} hicn_face_counters_t;
+extern mhash_t hicn_face_hashtb;
+
extern const char *HICN_FACE_CTRX_STRING[];
#define get_face_counter_string(ctrxno) (char *)(HICN_FACE_CTRX_STRING[ctrxno])
@@ -174,7 +196,7 @@ extern dpo_type_t first_type;
extern vlib_combined_counter_main_t *counters;
/**
- * @brief Return the face id from the face state
+ * @brief Return the face id from the face object
*
* @param Pointer to the face state
* @return face id
@@ -186,6 +208,22 @@ hicn_dpoi_get_index (hicn_face_t * face_dpoi)
}
/**
+ * @brief Return the face object from the face id.
+ * This method is robust to invalid face id.
+ *
+ * @param dpoi_index Face identifier
+ * @return Pointer to the face or NULL
+ */
+always_inline hicn_face_t *
+hicn_dpoi_get_from_idx_safe (hicn_face_id_t dpoi_index)
+{
+ if (!pool_is_free_index(hicn_dpoi_face_pool, dpoi_index))
+ return (hicn_face_t *) pool_elt_at_index (hicn_dpoi_face_pool, dpoi_index);
+ else
+ return NULL;
+}
+
+/**
* @brief Return the face from the face id. Face id must be valid.
*
* @param dpoi_index Face identifier
@@ -207,17 +245,18 @@ hicn_dpoi_idx_is_valid (hicn_face_id_t face_id)
&& !pool_is_free_index (hicn_dpoi_face_pool, face_id);
}
+
/**
* @brief Add a lock to the face dpo
*
* @param dpo Pointer to the face dpo
*/
always_inline void
-hicn_face_lock (dpo_id_t * dpo)
+hicn_face_lock_with_id (hicn_face_id_t face_id)
{
hicn_face_t *face;
- face = hicn_dpoi_get_from_idx (dpo->dpoi_index);
- face->shared.locks++;
+ face = hicn_dpoi_get_from_idx (face_id);
+ face->locks++;
}
/**
@@ -226,20 +265,46 @@ hicn_face_lock (dpo_id_t * dpo)
* @param dpo Pointer to the face dpo
*/
always_inline void
-hicn_face_unlock (dpo_id_t * dpo)
+hicn_face_unlock_with_id (hicn_face_id_t face_id)
{
hicn_face_t *face;
- face = hicn_dpoi_get_from_idx (dpo->dpoi_index);
- face->shared.locks--;
+ face = hicn_dpoi_get_from_idx (face_id);
+ face->locks--;
+}
+
+/**
+ * @brief Add a lock to the face through its dpo
+ *
+ * @param dpo Pointer to the face dpo
+ */
+always_inline void
+hicn_face_lock (dpo_id_t * dpo)
+{
+ hicn_face_lock_with_id(dpo->dpoi_index);
}
/**
+ * @brief Remove a lock to the face through its dpo. Deallocate the face id locks == 0
+ *
+ * @param dpo Pointer to the face dpo
+ */
+always_inline void
+hicn_face_unlock (dpo_id_t * dpo)
+{
+ hicn_face_unlock_with_id (dpo->dpoi_index);
+}
+
+
+/**
* @brief Init the internal structures of the face module
*
* Must be called before processing any packet
*/
void hicn_face_module_init (vlib_main_t * vm);
+u8 * format_hicn_face (u8 * s, va_list * args);
+
+
/**
* @brief Format all the existing faces
*
@@ -259,21 +324,469 @@ u8 *format_hicn_face_all (u8 * s, int n, ...);
int hicn_face_del (hicn_face_id_t face_id);
/**
- * @brief Return the virtual function table corresponding to the face type
+ * @bried vector of faces used to collect faces having the same local address
+ *
+ */
+typedef hicn_face_id_t *hicn_face_vec_t;
+
+typedef struct hicn_input_faces_s_
+{
+ /* Vector of all possible input faces */
+ u32 vec_id;
+
+ /* Preferred face. If an prod_app face is in the vector it will be the preferred one. */
+ /* It's not possible to have multiple prod_app face in the same vector, they would have */
+ /* the same local address. Every prod_app face is a point-to-point face between the forwarder */
+ /* and the application. */
+ hicn_face_id_t face_id;
+
+} hicn_face_input_faces_t;
+
+/**
+ * Pool containing the vector of possible incoming faces.
+ */
+extern hicn_face_vec_t *hicn_vec_pool;
+
+/**
+ * Hash tables that indexes a face by remote address. For fast lookup when an
+ * interest arrives.
+ */
+extern mhash_t hicn_face_vec_hashtb;
+
+
+/**
+ * Key definition for the mhash table. An face is uniquely identified by ip
+ * address, the interface id and a dpo pointing to the next node in the vlib graph.
+ * The ip address can correspond to the remote ip address of the next hicn hop,
+ * or to the local address of the receiving interface. The former is used to
+ * retrieve the incoming face when an interest is received, the latter when
+ * the arring packet is a data. If the face is a regular face
+ * In case of iface, the following structure can be filled in different ways:
+ * - dpo equal to DPO_INVALID when the iface is a regular hICN iface
+ * - in case of udp_tunnel dpo =
+ * {
+ * .dpoi_index = tunnel_id,
+ * .dpoi_type = DPO_FIRST, //We don't need the type, we leave it invalid
+ * .dpoi_proto = DPO_PROTO_IP4 or DPO_PROTO_IP6,
+ * .dpoi_next_node = HICN6_IFACE_OUTPUT_NEXT_UDP4_ENCAP or
+ * HICN6_IFACE_OUTPUT_NEXT_UDP6_ENCAP or
+ * HICN4_IFACE_OUTPUT_NEXT_UDP4_ENCAP or
+ * HICN4_IFACE_OUTPUT_NEXT_UDP6_ENCAP
+ * }
+ */
+typedef struct __attribute__ ((packed)) hicn_face_key_s
+{
+ ip46_address_t addr;
+ union {
+ dpo_id_t dpo;
+ u64 align_dpo;
+ };
+ u32 sw_if;
+} hicn_face_key_t;
+
+/**
+ * @brief Create the key object for the mhash. Fill in the key object with the
+ * expected values.
+ *
+ * @param addr nat address of the face
+ * @param sw_if interface associated to the face
+ * @param key Pointer to an allocated hicn_face_ip_key_t object
+ */
+always_inline void
+hicn_face_get_key (const ip46_address_t * addr,
+ u32 sw_if, const dpo_id_t * dpo, hicn_face_key_t * key)
+{
+ key->dpo = *dpo;
+ key->addr = *addr;
+ key->sw_if = sw_if;
+}
+
+/**
+ * @brief Get the face obj from the nat address. Does not add any lock.
+ *
+ * @param addr Ip v4 address used to create the key for the hash table.
+ * @param sw_if Software interface id used to create the key for the hash table.
+ * @param hashtb Hash table (remote or local) where to perform the lookup.
+ *
+ * @result Pointer to the face.
+ */
+always_inline hicn_face_t *
+hicn_face_get (const ip46_address_t * addr, u32 sw_if, mhash_t * hashtb, index_t adj_index)
+{
+ hicn_face_key_t key;
+
+ dpo_id_t dpo = DPO_INVALID;
+
+ dpo.dpoi_index = adj_index;
+
+ hicn_face_get_key (addr, sw_if, &dpo, &key);
+
+ hicn_face_id_t *dpoi_index = (hicn_face_id_t *) mhash_get (hashtb,
+ &key);
+
+ if ( dpoi_index != NULL)
+ {
+ hicn_face_lock_with_id(*dpoi_index);
+ return hicn_dpoi_get_from_idx (*dpoi_index);
+ }
+
+ return NULL;
+}
+
+/**
+ * @brief Get the face obj from the nat address and the dpo. Does not add any lock.
+ *
+ * @param addr Ip v4 address used to create the key for the hash table.
+ * @param sw_if Software interface id used to create the key for the hash table.
+ * @param hashtb Hash table (remote or local) where to perform the lookup.
*
- * @param face_type Type of the face
- * @return NULL if the face type does not exist
+ * @result Pointer to the face.
*/
-hicn_face_vft_t *hicn_face_get_vft (hicn_face_type_t face_type);
+always_inline hicn_face_t *
+hicn_face_get_with_dpo (const ip46_address_t * addr, u32 sw_if, const dpo_id_t * dpo, mhash_t * hashtb)
+{
+ hicn_face_key_t key;
+
+ hicn_face_get_key (addr, sw_if, dpo, &key);
+
+ hicn_face_id_t *dpoi_index = (hicn_face_id_t *) mhash_get (hashtb,
+ &key);
+
+ if ( dpoi_index != NULL)
+ {
+ hicn_face_lock_with_id(*dpoi_index);
+ return hicn_dpoi_get_from_idx (*dpoi_index);
+ }
+
+ return NULL;
+}
/**
- * @brief Register a new face type
+ * @brief Get the vector of faces from the ip v4 address. Does not add any lock.
+ *
+ * @param addr Ip v4 address used to create the key for the hash table.
+ * @param sw_if Software interface id used to create the key for the hash table.
+ * @param hashtb Hash table (remote or local) where to perform the lookup.
*
- * @param face_type Type of the face
- * @param vft Virtual Function table for the new face type
+ * @result Pointer to the face.
*/
-void register_face_type (hicn_face_type_t face_type, hicn_face_vft_t * vft,
- char *name);
+always_inline hicn_face_input_faces_t *
+hicn_face_get_vec (const ip46_address_t * addr,
+ mhash_t * hashtb)
+{
+ hicn_face_key_t key;
+
+ dpo_id_t dpo = DPO_INVALID;
+
+ hicn_face_get_key (addr, 0, &dpo, &key);
+ return (hicn_face_input_faces_t *) mhash_get (hashtb, &key);
+}
+
+/**
+ * @brief Create a new face ip. API for other modules (e.g., routing)
+ *
+ * @param dpo_nh dpo contained in the face that points to the next node in
+ * the vlib graph
+ * @param nat_addr nat ip v4 or v6 address of the face
+ * @param sw_if interface associated to the face
+ * @param pfaceid Pointer to return the face id
+ * @param is_app_prod if HICN_FACE_FLAGS_APPFACE_PROD the face is a local application face, all other values are ignored
+ * @return HICN_ERROR_FACE_NO_GLOBAL_IP if the face does not have a globally
+ * reachable ip address, otherwise HICN_ERROR_NONE
+ */
+int hicn_face_add (const dpo_id_t * dpo_nh,
+ ip46_address_t * nat_address,
+ int sw_if,
+ hicn_face_id_t * pfaceid,
+ u8 is_app_prod);
+
+/**
+ * @brief Create a new incomplete face ip. (Meant to be used by the data plane)
+ *
+ * @param local_addr Local ip v4 or v6 address of the face
+ * @param remote_addr Remote ip v4 or v6 address of the face
+ * @param sw_if interface associated to the face
+ * @param pfaceid Pointer to return the face id
+ * @return HICN_ERROR_FACE_NO_GLOBAL_IP if the face does not have a globally
+ * reachable ip address, otherwise HICN_ERROR_NONE
+ */
+always_inline void
+hicn_iface_add (ip46_address_t * nat_address, int sw_if,
+ hicn_face_id_t * pfaceid, dpo_proto_t proto,
+ u32 adj_index)
+{
+ hicn_face_t *face;
+ pool_get (hicn_dpoi_face_pool, face);
+
+ clib_memcpy (&(face->nat_addr), nat_address,
+ sizeof (ip46_address_t));
+ face->sw_if = sw_if;
+
+ face->dpo.dpoi_type = DPO_FIRST;
+ face->dpo.dpoi_proto = DPO_PROTO_NONE;
+ face->dpo.dpoi_index = adj_index;
+ face->dpo.dpoi_next_node = 0;
+ face->pl_id = (u16) 0;
+ face->flags = HICN_FACE_FLAGS_IFACE;
+ face->locks = 1;
+
+ hicn_face_key_t key;
+ hicn_face_get_key (nat_address, sw_if, &face->dpo, &key);
+ *pfaceid = hicn_dpoi_get_index (face);
+
+ mhash_set_mem (&hicn_face_hashtb, &key, (uword *) pfaceid, 0);
+
+ for (int i = 0; i < HICN_N_COUNTER; i++)
+ {
+ vlib_validate_combined_counter (&counters[(*pfaceid) * HICN_N_COUNTER],
+ i);
+ vlib_zero_combined_counter (&counters[(*pfaceid) * HICN_N_COUNTER], i);
+ }
+}
+
+/**** Helpers to manipulate faces and ifaces from the face/iface input nodes ****/
+
+/**
+ * @brief Retrieve a vector of faces from the ip4 local address and returns its index.
+ *
+ * @param vec: Result of the lookup. If no face exists for the local address vec = NULL
+ * @param hicnb_flags: Flags that indicate whether the face is an application
+ * face or not
+ * @param local_addr: Ip v4 nat address of the face
+ * @param sw_if: software interface id of the face
+ *
+ * @result HICN_ERROR_FACE_NOT_FOUND if the face does not exist, otherwise HICN_ERROR_NONE.
+ */
+always_inline int
+hicn_face_ip4_lock (hicn_face_id_t * face_id,
+ u32 * in_faces_vec_id,
+ u8 * hicnb_flags,
+ const ip4_address_t * nat_addr)
+{
+ ip46_address_t ip_address = {0};
+ ip46_address_set_ip4(&ip_address, nat_addr);
+ hicn_face_input_faces_t *in_faces_vec =
+ hicn_face_get_vec (&ip_address, &hicn_face_vec_hashtb);
+
+ if (PREDICT_FALSE (in_faces_vec == NULL))
+ return HICN_ERROR_FACE_NOT_FOUND;
+
+ *in_faces_vec_id = in_faces_vec->vec_id;
+ hicn_face_t *face = hicn_dpoi_get_from_idx (in_faces_vec->face_id);
+
+ *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
+ *hicnb_flags |=
+ (face->flags & HICN_FACE_FLAGS_APPFACE_PROD) >>
+ HICN_FACE_FLAGS_APPFACE_PROD_BIT;
+
+ *face_id = in_faces_vec->face_id;
+
+ return HICN_ERROR_NONE;
+}
+
+/**
+ * @brief Retrieve a face from the ip6 local address and returns its dpo. This
+ * method adds a lock on the face state.
+ *
+ * @param dpo: Result of the lookup. If the face doesn't exist dpo = NULL
+ * @param hicnb_flags: Flags that indicate whether the face is an application
+ * face or not
+ * @param nat_addr: Ip v6 nat address of the face
+ * @param sw_if: software interface id of the face
+ *
+ * @result HICN_ERROR_FACE_NOT_FOUND if the face does not exist, otherwise HICN_ERROR_NONE.
+ */
+always_inline int
+hicn_face_ip6_lock (hicn_face_id_t * face_id,
+ u32 * in_faces_vec_id,
+ u8 * hicnb_flags,
+ const ip6_address_t * nat_addr)
+{
+ hicn_face_input_faces_t *in_faces_vec =
+ hicn_face_get_vec ((ip46_address_t *)nat_addr, &hicn_face_vec_hashtb);
+
+ if (PREDICT_FALSE (in_faces_vec == NULL))
+ return HICN_ERROR_FACE_NOT_FOUND;
+
+ *in_faces_vec_id = in_faces_vec->vec_id;
+ hicn_face_t *face = hicn_dpoi_get_from_idx (in_faces_vec->face_id);
+
+ *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
+ *hicnb_flags |=
+ (face->flags & HICN_FACE_FLAGS_APPFACE_PROD) >>
+ HICN_FACE_FLAGS_APPFACE_PROD_BIT;
+
+ *face_id = in_faces_vec->face_id;
+
+ return HICN_ERROR_NONE;
+}
+
+/**
+ * @brief Call back to get the adj of the tunnel
+ */
+static adj_walk_rc_t
+hicn4_iface_adj_walk_cb (adj_index_t ai,
+ void *ctx)
+{
+
+ hicn_face_t *face = (hicn_face_t *)ctx;
+
+ dpo_set(&face->dpo, DPO_ADJACENCY_MIDCHAIN, DPO_PROTO_IP4, ai);
+ adj_nbr_midchain_stack(ai, &face->dpo);
+
+ return (ADJ_WALK_RC_CONTINUE);
+}
+
+/**
+ * @brief Retrieve, or create if it doesn't exist, a face from the ip6 local
+ * address and returns its dpo. This method adds a lock on the face state.
+ *
+ * @param dpo: Result of the lookup
+ * @param hicnb_flags: Flags that indicate whether the face is an application
+ * face or not
+ * @param nat_addr: Ip v4 remote address of the face
+ * @param sw_if: software interface id of the face
+ * @param node_index: vlib edge index to use in the packet processing
+ */
+always_inline void
+hicn_iface_ip4_add_and_lock (hicn_face_id_t * index,
+ u8 * hicnb_flags,
+ const ip4_address_t * nat_addr,
+ u32 sw_if, u32 adj_index, u32 node_index)
+{
+ /*All (complete) faces are indexed by remote addess as well */
+
+ ip46_address_t ip_address = {0};
+ ip46_address_set_ip4(&ip_address, nat_addr);
+
+ /* if the face exists, it adds a lock */
+ hicn_face_t *face =
+ hicn_face_get (&ip_address, sw_if, &hicn_face_hashtb, adj_index);
+
+ if (face == NULL)
+ {
+ hicn_face_id_t idx;
+ hicn_iface_add (&ip_address, sw_if, &idx, DPO_PROTO_IP4, adj_index);
+
+ face = hicn_dpoi_get_from_idx(idx);
+
+ face->dpo.dpoi_type = DPO_FIRST;
+ face->dpo.dpoi_proto = DPO_PROTO_IP4;
+ face->dpo.dpoi_index = adj_index;
+ face->dpo.dpoi_next_node = node_index;
+
+ /* if (nat_addr->as_u32 == 0) */
+ /* { */
+ adj_nbr_walk(face->sw_if,
+ FIB_PROTOCOL_IP4,
+ hicn4_iface_adj_walk_cb,
+ face);
+ /* } */
+
+ *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
+
+ *index = idx;
+ return;
+ }
+ else
+ {
+ /* unlock the face. We don't take a lock on each interest we receive */
+ hicn_face_id_t face_id = hicn_dpoi_get_index(face);
+ hicn_face_unlock_with_id(face_id);
+ }
+
+ /* 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);
+}
+
+/**
+ * @brief Call back to get the adj of the tunnel
+ */
+static adj_walk_rc_t
+hicn6_iface_adj_walk_cb (adj_index_t ai,
+ void *ctx)
+{
+
+ hicn_face_t *face = (hicn_face_t *)ctx;
+
+ ip_adjacency_t *adj = adj_get(ai);
+ if ((adj->lookup_next_index == IP_LOOKUP_NEXT_MIDCHAIN) ||
+ (adj->lookup_next_index == IP_LOOKUP_NEXT_MCAST_MIDCHAIN))
+ {
+ dpo_set(&face->dpo, DPO_ADJACENCY_MIDCHAIN, adj->ia_nh_proto, ai);
+ adj_nbr_midchain_stack(ai, &face->dpo);
+ }
+
+ return (ADJ_WALK_RC_CONTINUE);
+}
+
+
+/**
+ * @brief Retrieve, or create if it doesn't exist, a face from the ip6 local
+ * address and returns its dpo. This method adds a lock on the face state.
+ *
+ * @param dpo: Result of the lookup
+ * @param hicnb_flags: Flags that indicate whether the face is an application
+ * face or not
+ * @param nat_addr: Ip v6 remote address of the face
+ * @param sw_if: software interface id of the face
+ * @param node_index: vlib edge index to use in the packet processing
+ */
+always_inline void
+hicn_iface_ip6_add_and_lock (hicn_face_id_t * index,
+ u8 * hicnb_flags,
+ const ip6_address_t * nat_addr,
+ u32 sw_if, u32 adj_index, u32 node_index)
+{
+ /*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_hashtb, adj_index);
+
+ if (face == NULL)
+ {
+ hicn_face_id_t idx;
+ hicn_iface_add ((ip46_address_t *) nat_addr, sw_if, &idx, DPO_PROTO_IP6, adj_index);
+
+ face = hicn_dpoi_get_from_idx(idx);
+
+ face->dpo.dpoi_type = DPO_FIRST;
+ face->dpo.dpoi_proto = DPO_PROTO_IP6;
+ face->dpo.dpoi_index = adj_index;
+ face->dpo.dpoi_next_node = node_index;
+
+ adj_nbr_walk(face->sw_if,
+ FIB_PROTOCOL_IP6,
+ hicn6_iface_adj_walk_cb,
+ face);
+
+ *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
+
+ *index = idx;
+
+ return;
+ }
+ else
+ {
+ /* unlock the face. We don't take a lock on each interest we receive */
+ hicn_face_id_t face_id = hicn_dpoi_get_index(face);
+ hicn_face_unlock_with_id(face_id);
+ }
+
+ /* 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);
+}
+
#endif // __HICN_FACE_H__
/*
diff --git a/hicn-plugin/src/faces/face_cli.c b/hicn-plugin/src/faces/face_cli.c
index b0ed7ddae..e9e516cc6 100644
--- a/hicn-plugin/src/faces/face_cli.c
+++ b/hicn-plugin/src/faces/face_cli.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -74,8 +74,7 @@ hicn_face_cli_show_command_fn (vlib_main_t * vm,
(HICN_ERROR_FACE_NOT_FOUND));
hicn_face_t *face = hicn_dpoi_get_from_idx (face_id);
- hicn_face_vft_t *vft = hicn_face_get_vft (face->shared.face_type);
- vlib_cli_output (vm, "%U\n", vft->format_face, face_id, 0 /*indent */ );
+ vlib_cli_output (vm, "%U\n", format_hicn_face, face_id, 0 /*indent */ );
u32 indent = 3;
@@ -107,16 +106,14 @@ hicn_face_cli_show_command_fn (vlib_main_t * vm,
if (found != ~0)
{
hicn_face_t *face;
- dpo_type_t type = (dpo_type_t) (found + first_type);
- hicn_face_vft_t *vft = hicn_face_get_vft (type);
/* *INDENT-OFF* */
pool_foreach(face, hicn_dpoi_face_pool,
{
- if (!((face->shared.flags & HICN_FACE_FLAGS_DELETED) && !deleted))
+ if (!((face->flags & HICN_FACE_FLAGS_DELETED) && !deleted))
{
- if ((face->shared.face_type == type) && (face->shared.flags))
+ if (face->flags)
{
- vlib_cli_output(vm, "%U\n", vft->format_face, hicn_dpoi_get_index(face), 0);
+ vlib_cli_output(vm, "%U\n", format_hicn_face, hicn_dpoi_get_index(face), 0);
u8 * s = 0;
u32 indent = 3;
@@ -147,10 +144,9 @@ hicn_face_cli_show_command_fn (vlib_main_t * vm,
/* *INDENT-OFF* */
pool_foreach(face, hicn_dpoi_face_pool,
{
- if (!((face->shared.flags & HICN_FACE_FLAGS_DELETED) && !deleted))
+ if (!((face->flags & HICN_FACE_FLAGS_DELETED) && !deleted))
{
- hicn_face_vft_t * vft = hicn_face_get_vft(face->shared.face_type);
- vlib_cli_output(vm, "%U\n", vft->format_face, hicn_dpoi_get_index(face), 0);
+ vlib_cli_output(vm, "%U\n", format_hicn_face, hicn_dpoi_get_index(face), 0);
u32 indent = 3;
u8 * s = 0;
@@ -184,7 +180,7 @@ hicn_face_cli_show_command_fn (vlib_main_t * vm,
VLIB_CLI_COMMAND (hicn_face_cli_show_command, static) =
{
.path = "hicn face show",
- .short_help = "hicn face show [<face_id>| type <ip/udp>]",
+ .short_help = "hicn face show [<face_id>]",
.function = hicn_face_cli_show_command_fn,
};
/* *INDENT-ON* */
diff --git a/hicn-plugin/src/faces/ip/face_ip_node.c b/hicn-plugin/src/faces/face_node.c
index 0eeeab6fb..e1fd81ca0 100644
--- a/hicn-plugin/src/faces/ip/face_ip_node.c
+++ b/hicn-plugin/src/faces/face_node.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2020 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:
@@ -15,15 +15,13 @@
#include <vnet/adj/adj.h>
-#include "face_ip.h"
-#include "face_ip_node.h"
-#include "dpo_ip.h"
-#include "../app/face_prod.h"
-#include "../../strategy_dpo_manager.h"
-#include "../face.h"
-#include "../../cache_policies/cs_lru.h"
-#include "../../infra.h"
-#include "../../hicn.h"
+#include "face.h"
+#include "face_node.h"
+#include "../strategy_dpo_manager.h"
+#include "face.h"
+#include "../cache_policies/cs_lru.h"
+#include "../infra.h"
+#include "../hicn.h"
/**
* @File
@@ -31,21 +29,21 @@
* Definition of the nodes for ip incomplete faces.
*/
-vlib_node_registration_t hicn_face_ip4_input_node;
-vlib_node_registration_t hicn_face_ip4_output_node;
-vlib_node_registration_t hicn_face_ip6_input_node;
-vlib_node_registration_t hicn_face_ip6_output_node;
+vlib_node_registration_t hicn4_face_input_node;
+vlib_node_registration_t hicn4_face_output_node;
+vlib_node_registration_t hicn6_face_input_node;
+vlib_node_registration_t hicn6_face_output_node;
#define ip_v4 4
#define ip_v6 6
-static char *hicn_face_ip4_input_error_strings[] = {
+static char *hicn4_face_input_error_strings[] = {
#define _(sym, string) string,
foreach_hicnfwd_error
#undef _
};
-static char *hicn_face_ip6_input_error_strings[] = {
+static char *hicn6_face_input_error_strings[] = {
#define _(sym, string) string,
foreach_hicnfwd_error
#undef _
@@ -59,15 +57,15 @@ typedef struct
u8 pkt_type;
u8 packet_data[60];
}
-hicn_face_ip4_input_trace_t;
+hicn4_face_input_trace_t;
typedef enum
{
- HICN_FACE_IP4_INPUT_NEXT_DATA,
- HICN_FACE_IP4_INPUT_NEXT_MAPME,
- HICN_FACE_IP4_INPUT_NEXT_ERROR_DROP,
- HICN_FACE_IP4_INPUT_N_NEXT,
-} hicn_face_ip4_input_next_t;
+ HICN4_FACE_INPUT_NEXT_DATA,
+ HICN4_FACE_INPUT_NEXT_MAPME,
+ HICN4_FACE_INPUT_NEXT_ERROR_DROP,
+ HICN4_FACE_INPUT_N_NEXT,
+} hicn4_face_input_next_t;
/* Trace context struct */
typedef struct
@@ -77,35 +75,35 @@ typedef struct
u8 pkt_type;
u8 packet_data[60];
}
-hicn_face_ip6_input_trace_t;
+hicn6_face_input_trace_t;
typedef enum
{
- HICN_FACE_IP6_INPUT_NEXT_DATA,
- HICN_FACE_IP6_INPUT_NEXT_MAPME,
- HICN_FACE_IP6_INPUT_NEXT_ERROR_DROP,
- HICN_FACE_IP6_INPUT_N_NEXT,
-} hicn_face_ip6_input_next_t;
+ HICN6_FACE_INPUT_NEXT_DATA,
+ HICN6_FACE_INPUT_NEXT_MAPME,
+ HICN6_FACE_INPUT_NEXT_ERROR_DROP,
+ HICN6_FACE_INPUT_N_NEXT,
+} hicn6_face_input_next_t;
-#define NEXT_MAPME_IP4 HICN_FACE_IP4_INPUT_NEXT_MAPME
-#define NEXT_MAPME_IP6 HICN_FACE_IP6_INPUT_NEXT_MAPME
-#define NEXT_DATA_IP4 HICN_FACE_IP4_INPUT_NEXT_DATA
-#define NEXT_DATA_IP6 HICN_FACE_IP6_INPUT_NEXT_DATA
+#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_ERROR_DROP_IP4 HICN_FACE_IP4_INPUT_NEXT_ERROR_DROP
-#define NEXT_ERROR_DROP_IP6 HICN_FACE_IP6_INPUT_NEXT_ERROR_DROP
+#define NEXT_ERROR_DROP_IP4 HICN4_FACE_INPUT_NEXT_ERROR_DROP
+#define NEXT_ERROR_DROP_IP6 HICN6_FACE_INPUT_NEXT_ERROR_DROP
#define IP_HEADER_4 ip4_header_t
#define IP_HEADER_6 ip6_header_t
-#define LOCK_FROM_LOCAL_IP4 hicn_dpo_ip4_lock_from_local
-#define LOCK_FROM_LOCAL_IP6 hicn_dpo_ip6_lock_from_local
+#define LOCK_DPO_FACE_IP4 hicn_face_ip4_lock
+#define LOCK_DPO_FACE_IP6 hicn_face_ip6_lock
-#define TRACE_INPUT_PKT_IP4 hicn_face_ip4_input_trace_t
-#define TRACE_INPUT_PKT_IP6 hicn_face_ip6_input_trace_t
+#define TRACE_INPUT_PKT_IP4 hicn4_face_input_trace_t
+#define TRACE_INPUT_PKT_IP6 hicn6_face_input_trace_t
/*
- * NOTE: Both hicn_face_ip4_input_node_fn and hicn_face_ip6_input_node_fn
+ * NOTE: Both hicn4_face_input_node_fn and hicn6_face_input_node_fn
* present a similar codebase. Macro are hard to debug, although the
* followind code is pretty straighforward and most of the complexity is in
* functions that can be easily debug.
@@ -143,19 +141,18 @@ typedef enum
next0 = is_icmp*NEXT_MAPME_IP##ipv + \
(1-is_icmp)*NEXT_DATA_IP##ipv; \
\
- ret = LOCK_FROM_LOCAL_IP##ipv \
- (&(hicnb0->face_dpo_id), \
+ ret = LOCK_DPO_FACE_IP##ipv \
+ (&(hicnb0->face_id), \
&(hicnb0->in_faces_vec_id), \
&hicnb0->flags, \
- &(ip_hdr->dst_address), \
- vnet_buffer (b0)->sw_if_index[VLIB_RX]); \
+ &(ip_hdr->dst_address)); \
\
if ( PREDICT_FALSE(ret != HICN_ERROR_NONE) ) \
next0 = NEXT_ERROR_DROP_IP##ipv; \
else \
{ \
vlib_increment_combined_counter ( \
- &counters[hicnb0->face_dpo_id.dpoi_index \
+ &counters[hicnb0->face_id \
* HICN_N_COUNTER], thread_index, \
HICN_FACE_COUNTERS_DATA_RX, \
1, \
@@ -232,26 +229,24 @@ typedef enum
(1-is_icmp1)*NEXT_DATA_IP##ipv; \
\
\
- ret0 = LOCK_FROM_LOCAL_IP##ipv \
- (&(hicnb0->face_dpo_id), \
+ ret0 = LOCK_DPO_FACE_IP##ipv \
+ (&(hicnb0->face_id), \
&(hicnb0->in_faces_vec_id), \
&hicnb0->flags, \
- &(ip_hdr0->dst_address), \
- vnet_buffer (b0)->sw_if_index[VLIB_RX]); \
+ &(ip_hdr0->dst_address)); \
\
- ret1 = LOCK_FROM_LOCAL_IP##ipv \
- (&(hicnb1->face_dpo_id), \
+ ret1 = LOCK_DPO_FACE_IP##ipv \
+ (&(hicnb1->face_id), \
&(hicnb1->in_faces_vec_id), \
&hicnb1->flags, \
- &(ip_hdr1->dst_address), \
- vnet_buffer (b1)->sw_if_index[VLIB_RX]); \
+ &(ip_hdr1->dst_address)); \
\
if ( PREDICT_FALSE(ret0 != HICN_ERROR_NONE) ) \
next0 = NEXT_ERROR_DROP_IP##ipv; \
else \
{ \
vlib_increment_combined_counter ( \
- &counters[hicnb0->face_dpo_id.dpoi_index \
+ &counters[hicnb0->face_id \
* HICN_N_COUNTER], thread_index, \
HICN_FACE_COUNTERS_DATA_RX, \
1, \
@@ -264,7 +259,7 @@ typedef enum
else \
{ \
vlib_increment_combined_counter ( \
- &counters[hicnb1->face_dpo_id.dpoi_index \
+ &counters[hicnb1->face_id \
* HICN_N_COUNTER], thread_index,\
HICN_FACE_COUNTERS_DATA_RX, \
1, \
@@ -307,8 +302,8 @@ typedef enum
static uword
-hicn_face_ip4_input_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
- vlib_frame_t * frame)
+hicn4_face_input_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
+ vlib_frame_t * frame)
{
u32 n_left_from, *from, *to_next, next_index;
@@ -345,12 +340,12 @@ hicn_face_ip4_input_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
/* packet trace format function */
static u8 *
-hicn_face_ip4_input_format_trace (u8 * s, va_list * args)
+hicn4_face_input_format_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 *);
- hicn_face_ip4_input_trace_t *t =
- va_arg (*args, hicn_face_ip4_input_trace_t *);
+ hicn4_face_input_trace_t *t =
+ va_arg (*args, hicn4_face_input_trace_t *);
s = format (s, "FACE_IP4_INPUT: pkt: %d, sw_if_index %d, next index %d\n%U",
(int) t->pkt_type, t->sw_if_index, t->next_index,
@@ -363,32 +358,32 @@ hicn_face_ip4_input_format_trace (u8 * s, va_list * args)
* Node registration for the interest forwarder node
*/
/* *INDENT-OFF* */
-VLIB_REGISTER_NODE(hicn_face_ip4_input_node) =
+VLIB_REGISTER_NODE(hicn4_face_input_node) =
{
- .function = hicn_face_ip4_input_node_fn,
- .name = "hicn-face-ip4-input",
+ .function = hicn4_face_input_node_fn,
+ .name = "hicn4-face-input",
.vector_size = sizeof(u32),
- .format_trace = hicn_face_ip4_input_format_trace,
+ .format_trace = hicn4_face_input_format_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN(hicn_face_ip4_input_error_strings),
- .error_strings = hicn_face_ip4_input_error_strings,
- .n_next_nodes = HICN_FACE_IP4_INPUT_N_NEXT,
+ .n_errors = ARRAY_LEN(hicn4_face_input_error_strings),
+ .error_strings = hicn4_face_input_error_strings,
+ .n_next_nodes = HICN4_FACE_INPUT_N_NEXT,
/* edit / add dispositions here */
.next_nodes =
{
- [HICN_FACE_IP4_INPUT_NEXT_DATA] = "hicn-data-pcslookup",
- [HICN_FACE_IP4_INPUT_NEXT_MAPME] = "hicn-mapme-ack",
- [HICN_FACE_IP4_INPUT_NEXT_ERROR_DROP] = "error-drop",
+ [HICN4_FACE_INPUT_NEXT_DATA] = "hicn-data-pcslookup",
+ [HICN4_FACE_INPUT_NEXT_MAPME] = "hicn-mapme-ack",
+ [HICN4_FACE_INPUT_NEXT_ERROR_DROP] = "error-drop",
},
};
/* *INDENT-ON* */
/**
* @brief IPv6 face input node function
- * @see hicn_face_ip4_input_node_fn
+ * @see hicn6_face_input_node_fn
*/
static uword
-hicn_face_ip6_input_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
+hicn6_face_input_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
vlib_frame_t * frame)
{
u32 n_left_from, *from, *to_next, next_index;
@@ -426,12 +421,12 @@ hicn_face_ip6_input_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
/* packet trace format function */
static u8 *
-hicn_face_ip6_input_format_trace (u8 * s, va_list * args)
+hicn6_face_input_format_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 *);
- hicn_face_ip6_input_trace_t *t =
- va_arg (*args, hicn_face_ip6_input_trace_t *);
+ hicn6_face_input_trace_t *t =
+ va_arg (*args, hicn6_face_input_trace_t *);
s = format (s, "FACE_IP6_INPUT: pkt: %d, sw_if_index %d, next index %d\n%U",
(int) t->pkt_type, t->sw_if_index, t->next_index,
@@ -443,22 +438,22 @@ hicn_face_ip6_input_format_trace (u8 * s, va_list * args)
* Node registration for the interest forwarder node
*/
/* *INDENT-OFF* */
-VLIB_REGISTER_NODE(hicn_face_ip6_input_node) =
+VLIB_REGISTER_NODE(hicn6_face_input_node) =
{
- .function = hicn_face_ip6_input_node_fn,
- .name = "hicn-face-ip6-input",
+ .function = hicn6_face_input_node_fn,
+ .name = "hicn6-face-input",
.vector_size = sizeof(u32),
- .format_trace = hicn_face_ip6_input_format_trace,
+ .format_trace = hicn6_face_input_format_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN(hicn_face_ip6_input_error_strings),
- .error_strings = hicn_face_ip6_input_error_strings,
- .n_next_nodes = HICN_FACE_IP6_INPUT_N_NEXT,
+ .n_errors = ARRAY_LEN(hicn6_face_input_error_strings),
+ .error_strings = hicn6_face_input_error_strings,
+ .n_next_nodes = HICN6_FACE_INPUT_N_NEXT,
/* edit / add dispositions here */
.next_nodes =
{
- [HICN_FACE_IP6_INPUT_NEXT_DATA] = "hicn-data-pcslookup",
- [HICN_FACE_IP6_INPUT_NEXT_MAPME] = "hicn-mapme-ack",
- [HICN_FACE_IP6_INPUT_NEXT_ERROR_DROP] = "error-drop",
+ [HICN6_FACE_INPUT_NEXT_DATA] = "hicn-data-pcslookup",
+ [HICN6_FACE_INPUT_NEXT_MAPME] = "hicn-mapme-ack",
+ [HICN6_FACE_INPUT_NEXT_ERROR_DROP] = "error-drop",
},
};
/* *INDENT-ON* */
@@ -467,87 +462,91 @@ VLIB_REGISTER_NODE(hicn_face_ip6_input_node) =
typedef enum
{
- HICN_FACE_IP4_NEXT_ECHO_REPLY = IP4_LOOKUP_N_NEXT,
- HICN_FACE_IP4_N_NEXT,
-} hicn_face_ip4_next_t;
+ HICN4_FACE_OUTPUT_NEXT_ECHO_REPLY,
+ HICN4_FACE_OUTPUT_NEXT_UDP4_ENCAP,
+ HICN4_FACE_OUTPUT_NEXT_UDP6_ENCAP,
+ HICN4_FACE_OUTPUT_N_NEXT,
+} hicn4_face_output_next_t;
typedef enum
{
- HICN_FACE_IP6_NEXT_ECHO_REPLY = IP6_LOOKUP_N_NEXT,
- HICN_FACE_IP6_N_NEXT,
-} hicn_face_ip6_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 = HICN_FACE_IP4_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 = HICN_FACE_IP6_NEXT_ECHO_REPLY;
- res = 1;
- }
- }
- return res;
-}
+ HICN6_FACE_OUTPUT_NEXT_ECHO_REPLY,
+ HICN6_FACE_OUTPUT_NEXT_UDP4_ENCAP,
+ HICN6_FACE_OUTPUT_NEXT_UDP6_ENCAP,
+ 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
@@ -555,68 +554,37 @@ hicn_face_rewrite_interest (vlib_main_t * vm, vlib_buffer_t * b0,
hicn_face_t * face, u32 * next)
{
- if ((face->shared.flags & HICN_FACE_FLAGS_APPFACE_PROD) && hicn_face_match_probe(b0, face, next))
- return;
+ /* if ((face->flags & HICN_FACE_FLAGS_APPFACE_PROD) && hicn_face_match_probe(b0, face, next)) */
+ /* return; */
hicn_header_t *hicn = vlib_buffer_get_current (b0);
- hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data;
+ //hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data;
ip46_address_t temp_addr;
ip46_address_reset (&temp_addr);
hicn_type_t type = hicn_get_buffer (b0)->type;
hicn_ops_vft[type.l1]->rewrite_interest (type, &hicn->protocol,
- &ip_face->local_addr, &temp_addr);
-
- int is_iface = 0;
- ip_adjacency_t *adj;
- if (PREDICT_FALSE (face->shared.adj == ~0))
- is_iface = 1;
- else
- adj = adj_get (face->shared.adj);
-
- /* In case the adj is not complete, we look if a better one exists, otherwise we send an arp request
- * This is necessary to account for the case in which when we create a face, there isn't a /128(/32) adjacency and we match with a more general route which is in glean state
- * In this case in fact, the general route will not be update upone receiving of a arp or neighbour responde, but a new /128(/32) will be created
- */
- if (PREDICT_FALSE
- (is_iface || adj->lookup_next_index < IP_LOOKUP_NEXT_REWRITE))
- {
- fib_prefix_t fib_pfx;
- fib_node_index_t fib_entry_index;
- fib_prefix_from_ip46_addr (&ip_face->remote_addr, &fib_pfx);
- fib_pfx.fp_len = ip46_address_is_ip4(&ip_face->remote_addr)? 32 : 128;
-
- u32 fib_index = fib_table_find_or_create_and_lock (fib_pfx.fp_proto,
- HICN_FIB_TABLE,
- FIB_SOURCE_PRIORITY_HI);
-
- fib_entry_index = fib_table_lookup (fib_index, &fib_pfx);
+ &face->nat_addr, &temp_addr);
- face->shared.adj = fib_entry_get_adj (fib_entry_index);
- face->shared.flags &= ~HICN_FACE_FLAGS_IFACE;
- face->shared.flags |= HICN_FACE_FLAGS_FACE;
-
- adj = adj_get (face->shared.adj);
-
- hicn_ops_vft[type.l1]->rewrite_data (type, &hicn->protocol,
- &ip_face->remote_addr, &temp_addr,
- 0);
- }
+ if (ip46_address_is_ip4(&face->nat_addr))
+ b0->flags |= VNET_BUFFER_F_OFFLOAD_IP_CKSUM;
- vnet_buffer (b0)->ip.adj_index[VLIB_TX] = face->shared.adj;
- *next = adj->lookup_next_index;
+ b0->flags |= VNET_BUFFER_F_OFFLOAD_TCP_CKSUM;
+ ASSERT(face->flags & HICN_FACE_FLAGS_FACE);
+ vnet_buffer (b0)->ip.adj_index[VLIB_TX] = face->dpo.dpoi_index;
+ *next = face->dpo.dpoi_next_node;
}
-static char *hicn_face_ip4_output_error_strings[] = {
+static char *hicn4_face_output_error_strings[] = {
#define _(sym, string) string,
foreach_hicnfwd_error
#undef _
};
-static char *hicn_face_ip6_output_error_strings[] = {
+static char *hicn6_face_output_error_strings[] = {
#define _(sym, string) string,
foreach_hicnfwd_error
#undef _
@@ -631,7 +599,7 @@ typedef struct
u8 pkt_type;
u8 packet_data[60];
}
-hicn_face_ip4_output_trace_t;
+hicn4_face_output_trace_t;
/* Trace context struct */
typedef struct
@@ -641,16 +609,16 @@ typedef struct
u8 pkt_type;
u8 packet_data[60];
}
-hicn_face_ip6_output_trace_t;
+hicn6_face_output_trace_t;
-#define TRACE_OUTPUT_PKT_IP4 hicn_face_ip4_output_trace_t
-#define TRACE_OUTPUT_PKT_IP6 hicn_face_ip6_output_trace_t
+#define TRACE_OUTPUT_PKT_IP4 hicn4_face_output_trace_t
+#define TRACE_OUTPUT_PKT_IP6 hicn6_face_output_trace_t
#define face_output_x1(ipv) \
do { \
vlib_buffer_t *b0; \
u32 bi0; \
- u32 next0 = IP_LOOKUP_NEXT_DROP; \
+ u32 next0 = ~0; \
hicn_face_t * face; \
\
/* Prefetch for next iteration. */ \
@@ -712,8 +680,8 @@ hicn_face_ip6_output_trace_t;
do { \
vlib_buffer_t *b0, *b1; \
u32 bi0, bi1; \
- u32 next0 = IP_LOOKUP_NEXT_DROP; \
- u32 next1 = IP_LOOKUP_NEXT_DROP; \
+ u32 next0 = ~0; \
+ u32 next1 = ~0; \
hicn_face_t *face0, *face1; \
\
/* Prefetch for next iteration. */ \
@@ -807,7 +775,7 @@ hicn_face_ip6_output_trace_t;
static uword
-hicn_face_ip4_output_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
+hicn4_face_output_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
vlib_frame_t * frame)
{
u32 n_left_from, *from, *to_next, next_index;
@@ -846,12 +814,12 @@ hicn_face_ip4_output_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
/* packet trace format function */
static u8 *
-hicn_face_ip4_output_format_trace (u8 * s, va_list * args)
+hicn4_face_output_format_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 *);
- hicn_face_ip4_output_trace_t *t =
- va_arg (*args, hicn_face_ip4_output_trace_t *);
+ hicn4_face_output_trace_t *t =
+ va_arg (*args, hicn4_face_output_trace_t *);
s =
format (s, "FACE_IP4_OUTPUT: pkt: %d, sw_if_index %d, next index %d\n%U",
@@ -864,38 +832,29 @@ hicn_face_ip4_output_format_trace (u8 * s, va_list * args)
* Node registration for the interest forwarder node
*/
/* *INDENT-OFF* */
-VLIB_REGISTER_NODE(hicn_face_ip4_output_node) =
+VLIB_REGISTER_NODE(hicn4_face_output_node) =
{
- .function = hicn_face_ip4_output_node_fn,
- .name = "hicn-face-ip4-output",
+ .function = hicn4_face_output_node_fn,
+ .name = "hicn4-face-output",
.vector_size = sizeof(u32),
- .format_trace = hicn_face_ip4_output_format_trace,
+ .format_trace = hicn4_face_output_format_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN(hicn_face_ip4_output_error_strings),
- .error_strings = hicn_face_ip4_output_error_strings,
- .n_next_nodes = HICN_FACE_IP4_N_NEXT,
+ .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 =
{
- [IP_LOOKUP_NEXT_DROP] = "ip4-drop",
- [IP_LOOKUP_NEXT_PUNT] = "ip4-punt",
- [IP_LOOKUP_NEXT_LOCAL] = "ip4-local",
- [IP_LOOKUP_NEXT_ARP] = "ip4-arp",
- [IP_LOOKUP_NEXT_GLEAN] = "ip4-glean",
- [IP_LOOKUP_NEXT_REWRITE] = "ip4-rewrite",
- [IP_LOOKUP_NEXT_MCAST] = "ip4-rewrite-mcast",
- [IP_LOOKUP_NEXT_BCAST] = "ip4-rewrite-bcast",
- [IP_LOOKUP_NEXT_MIDCHAIN] = "ip4-midchain",
- [IP_LOOKUP_NEXT_MCAST_MIDCHAIN] = "ip4-mcast-midchain",
- [IP_LOOKUP_NEXT_ICMP_ERROR] = "ip4-icmp-error",
- [HICN_FACE_IP4_NEXT_ECHO_REPLY] = "hicn-face-ip4-input",
+ [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"
}
};
/* *INDENT-ON* */
static uword
-hicn_face_ip6_output_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
+hicn6_face_output_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
vlib_frame_t * frame)
{
u32 n_left_from, *from, *to_next, next_index;
@@ -934,12 +893,12 @@ hicn_face_ip6_output_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
/* packet trace format function */
static u8 *
-hicn_face_ip6_output_format_trace (u8 * s, va_list * args)
+hicn6_face_output_format_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 *);
- hicn_face_ip6_output_trace_t *t =
- va_arg (*args, hicn_face_ip6_output_trace_t *);
+ hicn6_face_output_trace_t *t =
+ va_arg (*args, hicn6_face_output_trace_t *);
s =
format (s, "FACE_IP6_OUTPUT: pkt: %d, sw_if_index %d, next index %d\n%U",
@@ -952,34 +911,22 @@ hicn_face_ip6_output_format_trace (u8 * s, va_list * args)
* Node registration for the interest forwarder node
*/
/* *INDENT-OFF* */
-VLIB_REGISTER_NODE(hicn_face_ip6_output_node) =
+VLIB_REGISTER_NODE(hicn6_face_output_node) =
{
- .function = hicn_face_ip6_output_node_fn,
- .name = "hicn-face-ip6-output",
+ .function = hicn6_face_output_node_fn,
+ .name = "hicn6-face-output",
.vector_size = sizeof(u32),
- .format_trace = hicn_face_ip6_output_format_trace,
+ .format_trace = hicn6_face_output_format_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN(hicn_face_ip6_output_error_strings),
- .error_strings = hicn_face_ip6_output_error_strings,
- .n_next_nodes = HICN_FACE_IP6_N_NEXT,
+ .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 =
{
- [IP_LOOKUP_NEXT_DROP] = "ip6-drop",
- [IP_LOOKUP_NEXT_PUNT] = "ip6-punt",
- [IP_LOOKUP_NEXT_LOCAL] = "ip6-local",
- [IP_LOOKUP_NEXT_ARP] = "ip6-discover-neighbor",
- [IP_LOOKUP_NEXT_GLEAN] = "ip6-glean",
- [IP_LOOKUP_NEXT_REWRITE] = "ip6-rewrite",
- [IP_LOOKUP_NEXT_BCAST] = "ip6-rewrite-bcast",
- [IP_LOOKUP_NEXT_MCAST] = "ip6-rewrite-mcast",
- [IP_LOOKUP_NEXT_MIDCHAIN] = "ip6-midchain",
- [IP_LOOKUP_NEXT_MCAST_MIDCHAIN] = "ip6-mcast-midchain",
- [IP_LOOKUP_NEXT_ICMP_ERROR] = "ip6-icmp-error",
- [IP6_LOOKUP_NEXT_HOP_BY_HOP] = "ip6-hop-by-hop",
- [IP6_LOOKUP_NEXT_ADD_HOP_BY_HOP] = "ip6-add-hop-by-hop",
- [IP6_LOOKUP_NEXT_POP_HOP_BY_HOP] = "ip6-pop-hop-by-hop",
- [HICN_FACE_IP6_NEXT_ECHO_REPLY] = "hicn-face-ip6-input"
+ [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"
}
};
/* *INDENT-ON* */
diff --git a/hicn-plugin/src/faces/face_node.h b/hicn-plugin/src/faces/face_node.h
new file mode 100644
index 000000000..f5a8bf5ae
--- /dev/null
+++ b/hicn-plugin/src/faces/face_node.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2020 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_NODE_H__
+#define __HICN_FACE_NODE_H__
+
+#include <vlib/vlib.h>
+#include <vnet/vnet.h>
+
+/**
+ * @file face_node.h
+ *
+ * Implements the input and output face nodes. Input face nodes
+ * process incoming data while output face nodes process outgoing
+ * interests packets.
+ *
+ * Input face nodes follow hicn-face-input nodes and their purpose
+ * is to retrieve the list of possible incoming faces for each the data packet.
+ * The following node to the input face nodes is the hicn-data-pcslookup.
+ * Output face nodes follow the strategy and the hicn-interest-hitpit nodes and
+ * they perform the src nat on each interest packet. The node following the
+ * output face nodes depends on the adjacency type. In case of ip, the following
+ * node is the ip-rewrite, in case of tunnels the next node is the one implementing
+ * the tunnel encapsulation (udp-encap, mpls, etc).
+ */
+
+extern vlib_node_registration_t hicn4_face_input_node;
+extern vlib_node_registration_t hicn4_face_output_node;
+extern vlib_node_registration_t hicn6_face_input_node;
+extern vlib_node_registration_t hicn6_face_output_node;
+
+#endif // __HICN_FACE_NODE_H__
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/hicn-plugin/src/faces/ip/iface_ip_node.c b/hicn-plugin/src/faces/iface_node.c
index 8adef50d9..433cf0b02 100644
--- a/hicn-plugin/src/faces/ip/iface_ip_node.c
+++ b/hicn-plugin/src/faces/iface_node.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2020 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:
@@ -13,13 +13,11 @@
* limitations under the License.
*/
-#include "face_ip.h"
-#include "dpo_ip.h"
-#include "../../strategy_dpo_manager.h"
-#include "../face.h"
-#include "../../hicn.h"
-#include "../../infra.h"
-#include "../../cache_policies/cs_lru.h"
+#include "face.h"
+#include "../strategy_dpo_manager.h"
+#include "../hicn.h"
+#include "../infra.h"
+#include "../cache_policies/cs_lru.h"
/**
* @File
@@ -27,43 +25,21 @@
* Definition of the nodes for ip incomplete faces.
*/
-vlib_node_registration_t hicn_iface_ip4_input_node;
-vlib_node_registration_t hicn_iface_ip4_output_node;
-vlib_node_registration_t hicn_iface_ip6_input_node;
-vlib_node_registration_t hicn_iface_ip6_output_node;
+vlib_node_registration_t hicn4_iface_input_node;
+vlib_node_registration_t hicn4_iface_output_node;
+vlib_node_registration_t hicn6_iface_input_node;
+vlib_node_registration_t hicn6_iface_output_node;
u32 data_fwd_iface_ip4_vlib_edge;
u32 data_fwd_iface_ip6_vlib_edge;
-void
-hicn_iface_ip_init (vlib_main_t * vm)
-{
- u32 temp_index4 = vlib_node_add_next (vm,
- hicn_interest_hitcs_node.index,
- hicn_iface_ip4_output_node.index);
- u32 temp_index6 = vlib_node_add_next (vm,
- hicn_interest_hitcs_node.index,
- hicn_iface_ip6_output_node.index);
-
- data_fwd_iface_ip4_vlib_edge = vlib_node_add_next (vm,
- hicn_data_fwd_node.index,
- hicn_iface_ip4_output_node.index);
-
- data_fwd_iface_ip6_vlib_edge = vlib_node_add_next (vm,
- hicn_data_fwd_node.index,
- hicn_iface_ip6_output_node.index);
-
- ASSERT (temp_index4 == data_fwd_iface_ip4_vlib_edge);
- ASSERT (temp_index6 == data_fwd_iface_ip6_vlib_edge);
-}
-
-static char *hicn_iface_ip4_input_error_strings[] = {
+static char *hicn4_iface_input_error_strings[] = {
#define _(sym, string) string,
foreach_hicnfwd_error
#undef _
};
-static char *hicn_iface_ip6_input_error_strings[] = {
+static char *hicn6_iface_input_error_strings[] = {
#define _(sym, string) string,
foreach_hicnfwd_error
#undef _
@@ -76,15 +52,15 @@ typedef struct
u32 sw_if_index;
u8 pkt_type;
u8 packet_data[60];
-} hicn_iface_ip4_input_trace_t;
+} hicn4_iface_input_trace_t;
typedef enum
{
- HICN_IFACE_IP4_INPUT_NEXT_INTEREST,
- HICN_IFACE_IP4_INPUT_NEXT_MAPME,
- HICN_IFACE_IP4_INPUT_NEXT_ERROR_DROP,
- HICN_IFACE_IP4_INPUT_N_NEXT,
-} hicn_iface_ip4_input_next_t;
+ HICN4_IFACE_INPUT_NEXT_INTEREST,
+ HICN4_IFACE_INPUT_NEXT_MAPME,
+ HICN4_IFACE_INPUT_NEXT_ERROR_DROP,
+ HICN4_IFACE_INPUT_N_NEXT,
+} hicn4_iface_input_next_t;
/* Trace context struct */
typedef struct
@@ -93,21 +69,21 @@ typedef struct
u32 sw_if_index;
u8 pkt_type;
u8 packet_data[60];
-} hicn_iface_ip6_input_trace_t;
+} hicn6_iface_input_trace_t;
typedef enum
{
- HICN_IFACE_IP6_INPUT_NEXT_INTEREST,
- HICN_IFACE_IP6_INPUT_NEXT_MAPME,
- HICN_IFACE_IP6_INPUT_NEXT_ERROR_DROP,
- HICN_IFACE_IP6_INPUT_N_NEXT,
-} hicn_iface_ip6_input_next_t;
+ HICN6_IFACE_INPUT_NEXT_INTEREST,
+ HICN6_IFACE_INPUT_NEXT_MAPME,
+ HICN6_IFACE_INPUT_NEXT_ERROR_DROP,
+ HICN6_IFACE_INPUT_N_NEXT,
+} hicn6_iface_input_next_t;
-#define NEXT_MAPME_IP4 HICN_IFACE_IP4_INPUT_NEXT_MAPME
-#define NEXT_MAPME_IP6 HICN_IFACE_IP6_INPUT_NEXT_MAPME
+#define NEXT_MAPME_IP4 HICN4_IFACE_INPUT_NEXT_MAPME
+#define NEXT_MAPME_IP6 HICN6_IFACE_INPUT_NEXT_MAPME
-#define NEXT_INTEREST_IP4 HICN_IFACE_IP6_INPUT_NEXT_INTEREST
-#define NEXT_INTEREST_IP6 HICN_IFACE_IP6_INPUT_NEXT_INTEREST
+#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)
@@ -119,25 +95,90 @@ typedef enum
#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_IP4 hicn_dpo_ip4_add_and_lock_from_remote
-#define DPO_ADD_LOCK_IP6 hicn_dpo_ip6_add_and_lock_from_remote
+#define DPO_ADD_LOCK_IFACE_IP4 hicn_iface_ip4_add_and_lock
+#define DPO_ADD_LOCK_IFACE_IP6 hicn_iface_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 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
-#define TRACE_INPUT_PKT_IP4 hicn_iface_ip4_input_trace_t
-#define TRACE_INPUT_PKT_IP6 hicn_iface_ip6_input_trace_t
+#define TRACE_INPUT_PKT_IP4 hicn4_iface_input_trace_t
+#define TRACE_INPUT_PKT_IP6 hicn6_iface_input_trace_t
+
+// NODE OUTPUT
+
+static char *hicn4_iface_output_error_strings[] = {
+#define _(sym, string) string,
+ foreach_hicnfwd_error
+#undef _
+};
+
+static char *hicn6_iface_output_error_strings[] = {
+#define _(sym, string) string,
+ foreach_hicnfwd_error
+#undef _
+};
+
+
+/* Trace context struct */
+typedef struct
+{
+ u32 next_index;
+ u32 sw_if_index;
+ u8 pkt_type;
+ u8 packet_data[60];
+} hicn4_iface_output_trace_t;
+
+typedef enum
+{
+ HICN4_IFACE_OUTPUT_NEXT_LOOKUP,
+ HICN4_IFACE_OUTPUT_NEXT_UDP4_ENCAP,
+ HICN4_IFACE_OUTPUT_NEXT_UDP6_ENCAP,
+ HICN4_IFACE_OUTPUT_N_NEXT,
+} hicn4_iface_output_next_t;
+
+/* Trace context struct */
+typedef struct
+{
+ u32 next_index;
+ u32 sw_if_index;
+ u8 pkt_type;
+ u8 packet_data[60];
+} hicn6_iface_output_trace_t;
+
+typedef enum
+{
+ HICN6_IFACE_OUTPUT_NEXT_LOOKUP,
+ HICN6_IFACE_OUTPUT_NEXT_UDP4_ENCAP,
+ HICN6_IFACE_OUTPUT_NEXT_UDP6_ENCAP,
+ HICN6_IFACE_OUTPUT_N_NEXT,
+} hicn6_iface_output_next_t;
+
+//#define ERROR_OUTPUT_IP4 HICN4_IFACE_OUTPUT_NEXT_ERROR_DROP
+//#define ERROR_OUTPUT_IP6 HICN6_IFACE_OUTPUT_NEXT_ERROR_DROP
+
+#define NEXT_DATA_LOOKUP_IP4 HICN4_IFACE_OUTPUT_NEXT_LOOKUP
+#define NEXT_DATA_LOOKUP_IP6 HICN6_IFACE_OUTPUT_NEXT_LOOKUP
+
+#define NEXT_UDP_ENCAP_IP4 HICN4_IFACE_OUTPUT_NEXT_UDP4_ENCAP
+#define NEXT_UDP_ENCAP_IP6 HICN6_IFACE_OUTPUT_NEXT_UDP6_ENCAP
+
+#define HICN_REWRITE_DATA_IP4 hicn_rewrite_iface_data4
+#define HICN_REWRITE_DATA_IP6 hicn_rewrite_iface_data6
+
+#define TRACE_OUTPUT_PKT_IP4 hicn4_iface_output_trace_t
+#define TRACE_OUTPUT_PKT_IP6 hicn6_iface_output_trace_t
+
+// NODES IMPLEMENTATIONS
#define iface_input_x1(ipv) \
do { \
vlib_buffer_t *b0; \
- u32 bi0, next0; \
+ u32 bi0, next0, next_iface0; \
IP_HEADER_##ipv * ip_hdr = NULL; \
hicn_buffer_t * hicnb0; \
- u32 swif; \
/* Prefetch for next iteration. */ \
if (n_left_from > 1) \
{ \
@@ -165,17 +206,20 @@ typedef enum
next0 = is_icmp*NEXT_MAPME_IP##ipv + \
(1-is_icmp)*NEXT_INTEREST_IP##ipv; \
\
- swif = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \
+ next_iface0 = NEXT_DATA_LOOKUP_IP##ipv; \
\
- ADDRESS_IP##ipv; \
+ if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL) \
+ next_iface0 = NEXT_UDP_ENCAP_IP4; \
+ else if(hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL) \
+ next_iface0 = NEXT_UDP_ENCAP_IP6; \
\
- DPO_ADD_LOCK_IP##ipv \
- (&(hicnb0->face_dpo_id), \
- &hicnb0->flags, \
- local_address, \
- &(ip_hdr->src_address), \
- vnet_buffer(b0)->sw_if_index[VLIB_RX], \
- VLIB_EDGE_IP##ipv); \
+ DPO_ADD_LOCK_IFACE_IP##ipv \
+ (&(hicnb0->face_id), \
+ &hicnb0->flags, \
+ &(ip_hdr->src_address), \
+ vnet_buffer(b0)->sw_if_index[VLIB_RX], \
+ 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))) \
@@ -192,11 +236,11 @@ typedef enum
} \
\
vlib_increment_combined_counter ( \
- &counters[hicnb0->face_dpo_id.dpoi_index \
- * HICN_N_COUNTER], thread_index, \
- HICN_FACE_COUNTERS_INTEREST_RX, \
- 1, \
- vlib_buffer_length_in_chain(vm, b0)); \
+ &counters[hicnb0->face_id \
+ * HICN_N_COUNTER], thread_index, \
+ HICN_FACE_COUNTERS_INTEREST_RX, \
+ 1, \
+ vlib_buffer_length_in_chain(vm, b0)); \
\
/* Verify speculative enqueue, maybe switch current next frame */ \
vlib_validate_buffer_enqueue_x1 (vm, node, next_index, \
@@ -208,11 +252,10 @@ typedef enum
#define iface_input_x2(ipv) \
do { \
vlib_buffer_t *b0, *b1; \
- u32 bi0, bi1, next0, next1; \
+ u32 bi0, bi1, next0, next1, next_iface0, next_iface1; \
IP_HEADER_##ipv * ip_hdr0 = NULL; \
IP_HEADER_##ipv * ip_hdr1 = NULL; \
hicn_buffer_t *hicnb0, *hicnb1; \
- u32 swif0, swif1; \
\
/* Prefetch for next iteration. */ \
vlib_buffer_t *b2, *b3; \
@@ -251,26 +294,35 @@ typedef enum
next1 = is_icmp1*NEXT_MAPME_IP##ipv + \
(1-is_icmp1)*NEXT_INTEREST_IP##ipv; \
\
- swif0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; \
- swif1 = vnet_buffer (b1)->sw_if_index[VLIB_RX]; \
+ next_iface0 = NEXT_DATA_LOOKUP_IP##ipv; \
+ \
+ if (hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL) \
+ next_iface0 = NEXT_UDP_ENCAP_IP4; \
+ else if(hicnb0->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL) \
+ next_iface0 = NEXT_UDP_ENCAP_IP6; \
\
- ADDRESSX2_IP##ipv; \
+ next_iface1 = NEXT_DATA_LOOKUP_IP##ipv; \
\
- DPO_ADD_LOCK_IP##ipv \
- (&(hicnb0->face_dpo_id), \
+ if (hicnb1->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL) \
+ next_iface1 = NEXT_UDP_ENCAP_IP4; \
+ else if(hicnb1->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL) \
+ next_iface1 = NEXT_UDP_ENCAP_IP6; \
+ \
+ DPO_ADD_LOCK_IFACE_IP##ipv \
+ (&(hicnb0->face_id), \
&hicnb0->flags, \
- local_address0, \
&(ip_hdr0->src_address), \
vnet_buffer(b0)->sw_if_index[VLIB_RX], \
- VLIB_EDGE_IP##ipv); \
+ vnet_buffer(b0)->ip.adj_index[VLIB_RX], \
+ next_iface0); \
\
- DPO_ADD_LOCK_IP##ipv \
- (&(hicnb1->face_dpo_id), \
+ DPO_ADD_LOCK_IFACE_IP##ipv \
+ (&(hicnb1->face_id), \
&hicnb1->flags, \
- local_address1, \
&(ip_hdr1->src_address), \
vnet_buffer(b1)->sw_if_index[VLIB_RX], \
- VLIB_EDGE_IP##ipv); \
+ 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))) \
@@ -299,14 +351,14 @@ typedef enum
} \
\
vlib_increment_combined_counter ( \
- &counters[hicnb0->face_dpo_id.dpoi_index \
+ &counters[hicnb0->face_id \
* HICN_N_COUNTER], thread_index, \
HICN_FACE_COUNTERS_INTEREST_RX, \
1, \
vlib_buffer_length_in_chain(vm, b0)); \
\
vlib_increment_combined_counter ( \
- &counters[hicnb1->face_dpo_id.dpoi_index \
+ &counters[hicnb1->face_id \
* HICN_N_COUNTER], thread_index, \
HICN_FACE_COUNTERS_INTEREST_RX, \
1, \
@@ -319,7 +371,7 @@ typedef enum
}while(0)
static uword
-hicn_iface_ip4_input_node_fn (vlib_main_t * vm,
+hicn4_iface_input_node_fn (vlib_main_t * vm,
vlib_node_runtime_t * node,
vlib_frame_t * frame)
{
@@ -359,12 +411,12 @@ hicn_iface_ip4_input_node_fn (vlib_main_t * vm,
/* packet trace format function */
static u8 *
-hicn_iface_ip4_input_format_trace (u8 * s, va_list * args)
+hicn4_iface_input_format_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 *);
- hicn_iface_ip4_input_trace_t *t =
- va_arg (*args, hicn_iface_ip4_input_trace_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",
@@ -377,28 +429,28 @@ hicn_iface_ip4_input_format_trace (u8 * s, va_list * args)
* Node registration for the interest forwarder node
*/
/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (hicn_iface_ip4_input_node) =
+VLIB_REGISTER_NODE (hicn4_iface_input_node) =
{
- .function = hicn_iface_ip4_input_node_fn,
- .name = "hicn-iface-ip4-input",
+ .function = hicn4_iface_input_node_fn,
+ .name = "hicn4-iface-input",
.vector_size = sizeof (u32),
- .format_trace = hicn_iface_ip4_input_format_trace,
+ .format_trace = hicn4_iface_input_format_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN (hicn_iface_ip4_input_error_strings),
- .error_strings = hicn_iface_ip4_input_error_strings,
- .n_next_nodes = HICN_IFACE_IP4_INPUT_N_NEXT,
+ .n_errors = ARRAY_LEN (hicn4_iface_input_error_strings),
+ .error_strings = hicn4_iface_input_error_strings,
+ .n_next_nodes = HICN4_IFACE_INPUT_N_NEXT,
/* edit / add dispositions*/
.next_nodes =
{
- [HICN_IFACE_IP4_INPUT_NEXT_INTEREST] = "hicn-interest-pcslookup",
- [HICN_IFACE_IP4_INPUT_NEXT_MAPME] = "hicn-mapme-ctrl",
- [HICN_IFACE_IP4_INPUT_NEXT_ERROR_DROP] = "error-drop",
+ [HICN4_IFACE_INPUT_NEXT_INTEREST] = "hicn-interest-pcslookup",
+ [HICN4_IFACE_INPUT_NEXT_MAPME] = "hicn-mapme-ctrl",
+ [HICN4_IFACE_INPUT_NEXT_ERROR_DROP] = "error-drop",
},
};
/* *INDENT-ON* */
static uword
-hicn_iface_ip6_input_node_fn (vlib_main_t * vm,
+hicn6_iface_input_node_fn (vlib_main_t * vm,
vlib_node_runtime_t * node,
vlib_frame_t * frame)
{
@@ -439,12 +491,12 @@ hicn_iface_ip6_input_node_fn (vlib_main_t * vm,
/* packet trace format function */
static u8 *
-hicn_iface_ip6_input_format_trace (u8 * s, va_list * args)
+hicn6_iface_input_format_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 *);
- hicn_iface_ip6_input_trace_t *t =
- va_arg (*args, hicn_iface_ip6_input_trace_t *);
+ hicn6_iface_input_trace_t *t =
+ va_arg (*args, hicn6_iface_input_trace_t *);
s =
format (s, "IFACE_IP6_INPUT: pkt: %d, sw_if_index %d, next index %d\n%U",
@@ -457,22 +509,22 @@ hicn_iface_ip6_input_format_trace (u8 * s, va_list * args)
* Node registration for the interest forwarder node
*/
/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (hicn_iface_ip6_input_node) =
+VLIB_REGISTER_NODE (hicn6_iface_input_node) =
{
- .function = hicn_iface_ip6_input_node_fn,
- .name = "hicn-iface-ip6-input",
+ .function = hicn6_iface_input_node_fn,
+ .name = "hicn6-iface-input",
.vector_size = sizeof (u32),
- .format_trace = hicn_iface_ip6_input_format_trace,
+ .format_trace = hicn6_iface_input_format_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN (hicn_iface_ip6_input_error_strings),
- .error_strings = hicn_iface_ip6_input_error_strings,
- .n_next_nodes = HICN_IFACE_IP6_INPUT_N_NEXT,
+ .n_errors = ARRAY_LEN (hicn6_iface_input_error_strings),
+ .error_strings = hicn6_iface_input_error_strings,
+ .n_next_nodes = HICN6_IFACE_INPUT_N_NEXT,
/* edit / add dispositions*/
.next_nodes =
{
- [HICN_IFACE_IP6_INPUT_NEXT_INTEREST] = "hicn-interest-pcslookup",
- [HICN_IFACE_IP6_INPUT_NEXT_MAPME] = "hicn-mapme-ctrl",
- [HICN_IFACE_IP6_INPUT_NEXT_ERROR_DROP] = "error-drop",
+ [HICN6_IFACE_INPUT_NEXT_INTEREST] = "hicn-interest-pcslookup",
+ [HICN6_IFACE_INPUT_NEXT_MAPME] = "hicn-mapme-ctrl",
+ [HICN6_IFACE_INPUT_NEXT_ERROR_DROP] = "error-drop",
},
};
/* *INDENT-ON* */
@@ -482,7 +534,7 @@ VLIB_REGISTER_NODE (hicn_iface_ip6_input_node) =
static inline void
hicn_rewrite_iface_data4 (vlib_main_t * vm, vlib_buffer_t * b0,
- const hicn_face_t * iface)
+ const hicn_face_t * iface, u32 * next)
{
ip4_header_t *ip0;
@@ -495,21 +547,21 @@ hicn_rewrite_iface_data4 (vlib_main_t * vm, vlib_buffer_t * b0,
ip0->length = clib_host_to_net_u16 (sval);
ip0->ttl = 254; // FIXME TTL
- vnet_buffer (b0)->ip.adj_index[VLIB_TX] = ~0;
+ vnet_buffer (b0)->ip.adj_index[VLIB_TX] = iface->dpo.dpoi_index;
+ *next = iface->dpo.dpoi_next_node;
hicn_header_t *hicn = vlib_buffer_get_current (b0);
ip46_address_t temp_addr;
ip46_address_reset (&temp_addr);
- hicn_face_ip_t *iface_ip = (hicn_face_ip_t *) iface->data;
hicn_type_t type = hicn_get_buffer (b0)->type;
hicn_ops_vft[type.l1]->rewrite_data (type, &hicn->protocol,
- &(iface_ip->remote_addr), &(temp_addr),
- iface->shared.pl_id);
+ &(iface->nat_addr), &(temp_addr),
+ iface->pl_id);
}
static inline void
hicn_rewrite_iface_data6 (vlib_main_t * vm, vlib_buffer_t * b0,
- const hicn_face_t * iface)
+ const hicn_face_t * iface, u32 * next)
{
ip6_header_t *ip0;
@@ -523,80 +575,24 @@ hicn_rewrite_iface_data6 (vlib_main_t * vm, vlib_buffer_t * b0,
ip0->payload_length = clib_host_to_net_u16 (sval);
ip0->hop_limit = HICN_IP6_HOP_LIMIT;
- vnet_buffer (b0)->ip.adj_index[VLIB_TX] = ~0;
+ vnet_buffer (b0)->ip.adj_index[VLIB_TX] = iface->dpo.dpoi_index;
+ *next = iface->dpo.dpoi_next_node;
+
hicn_header_t *hicn = vlib_buffer_get_current (b0);
ip46_address_t temp_addr;
ip46_address_reset (&temp_addr);
- hicn_face_ip_t *iface_ip = (hicn_face_ip_t *) iface->data;
hicn_type_t type = hicn_get_buffer (b0)->type;
hicn_ops_vft[type.l1]->rewrite_data (type, &hicn->protocol,
- &(iface_ip->remote_addr), &(temp_addr),
- iface->shared.pl_id);
+ &(iface->nat_addr), &(temp_addr),
+ iface->pl_id);
}
-static char *hicn_iface_ip4_output_error_strings[] = {
-#define _(sym, string) string,
- foreach_hicnfwd_error
-#undef _
-};
-
-static char *hicn_iface_ip6_output_error_strings[] = {
-#define _(sym, string) string,
- foreach_hicnfwd_error
-#undef _
-};
-
-
-/* Trace context struct */
-typedef struct
-{
- u32 next_index;
- u32 sw_if_index;
- u8 pkt_type;
- u8 packet_data[60];
-} hicn_iface_ip4_output_trace_t;
-
-typedef enum
-{
- HICN_IFACE_IP4_OUTPUT_NEXT_LOOKUP,
- HICN_IFACE_IP4_OUTPUT_NEXT_ERROR_DROP,
- HICN_IFACE_IP4_OUTPUT_N_NEXT,
-} hicn_iface_ip4_output_next_t;
-
-/* Trace context struct */
-typedef struct
-{
- u32 next_index;
- u32 sw_if_index;
- u8 pkt_type;
- u8 packet_data[60];
-} hicn_iface_ip6_output_trace_t;
-
-typedef enum
-{
- HICN_IFACE_IP6_OUTPUT_NEXT_LOOKUP,
- HICN_IFACE_IP6_OUTPUT_NEXT_ERROR_DROP,
- HICN_IFACE_IP6_OUTPUT_N_NEXT,
-} hicn_iface_ip6_output_next_t;
-
-#define ERROR_OUTPUT_IP4 HICN_IFACE_IP4_OUTPUT_NEXT_ERROR_DROP
-#define ERROR_OUTPUT_IP6 HICN_IFACE_IP6_OUTPUT_NEXT_ERROR_DROP
-
-#define NEXT_DATA_LOOKUP_IP4 HICN_IFACE_IP4_OUTPUT_NEXT_LOOKUP
-#define NEXT_DATA_LOOKUP_IP6 HICN_IFACE_IP6_OUTPUT_NEXT_LOOKUP
-
-#define HICN_REWRITE_DATA_IP4 hicn_rewrite_iface_data4
-#define HICN_REWRITE_DATA_IP6 hicn_rewrite_iface_data6
-
-#define TRACE_OUTPUT_PKT_IP4 hicn_iface_ip4_output_trace_t
-#define TRACE_OUTPUT_PKT_IP6 hicn_iface_ip6_output_trace_t
-
#define iface_output_x1(ipv) \
do { \
vlib_buffer_t *b0; \
u32 bi0; \
- u32 next0 = ERROR_OUTPUT_IP##ipv; \
+ u32 next0 = next_index; \
hicn_face_t * face; \
\
/* Prefetch for next iteration. */ \
@@ -624,8 +620,7 @@ typedef enum
if (PREDICT_TRUE(face != NULL)) \
{ \
HICN_REWRITE_DATA_IP##ipv \
- (vm, b0, face); \
- next0 = NEXT_DATA_LOOKUP_IP##ipv; \
+ (vm, b0, face, &next0); \
stats.pkts_data_count += 1; \
vlib_increment_combined_counter ( \
&counters[face_id * HICN_N_COUNTER], \
@@ -660,8 +655,8 @@ typedef enum
do { \
vlib_buffer_t *b0, *b1; \
u32 bi0, bi1; \
- u32 next0 = ERROR_OUTPUT_IP##ipv; \
- u32 next1 = ERROR_OUTPUT_IP##ipv; \
+ u32 next0 = next_index; \
+ u32 next1 = next_index; \
hicn_face_t *face0, *face1; \
\
/* Prefetch for next iteration. */ \
@@ -698,8 +693,7 @@ typedef enum
if (PREDICT_TRUE(face0 != NULL)) \
{ \
HICN_REWRITE_DATA_IP##ipv \
- (vm, b0, face0); \
- next0 = NEXT_DATA_LOOKUP_IP##ipv; \
+ (vm, b0, face0, &next0); \
stats.pkts_data_count += 1; \
vlib_increment_combined_counter ( \
&counters[face_id0 * HICN_N_COUNTER], \
@@ -712,8 +706,7 @@ typedef enum
if (PREDICT_TRUE(face1 != NULL)) \
{ \
HICN_REWRITE_DATA_IP##ipv \
- (vm, b1, face1); \
- next1 = NEXT_DATA_LOOKUP_IP##ipv; \
+ (vm, b1, face1, &next1); \
stats.pkts_data_count += 1; \
vlib_increment_combined_counter ( \
&counters[face_id1 * HICN_N_COUNTER], \
@@ -759,7 +752,7 @@ typedef enum
static uword
-hicn_iface_ip4_output_node_fn (vlib_main_t * vm,
+hicn4_iface_output_node_fn (vlib_main_t * vm,
vlib_node_runtime_t * node,
vlib_frame_t * frame)
{
@@ -797,12 +790,12 @@ hicn_iface_ip4_output_node_fn (vlib_main_t * vm,
/* packet trace format function */
static u8 *
-hicn_iface_ip4_output_format_trace (u8 * s, va_list * args)
+hicn4_iface_output_format_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 *);
- hicn_iface_ip4_output_trace_t *t =
- va_arg (*args, hicn_iface_ip4_output_trace_t *);
+ hicn4_iface_output_trace_t *t =
+ va_arg (*args, hicn4_iface_output_trace_t *);
s =
format (s, "IFACE_IP4_OUTPUT: pkt: %d, sw_if_index %d, next index %d\n%U",
@@ -815,28 +808,29 @@ hicn_iface_ip4_output_format_trace (u8 * s, va_list * args)
* Node registration for the interest forwarder node
*/
/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (hicn_iface_ip4_output_node) =
+VLIB_REGISTER_NODE (hicn4_iface_output_node) =
{
- .function = hicn_iface_ip4_output_node_fn,
- .name = "hicn-iface-ip4-output",
+ .function = hicn4_iface_output_node_fn,
+ .name = "hicn4-iface-output",
.vector_size = sizeof (u32),
- .format_trace = hicn_iface_ip4_output_format_trace,
+ .format_trace = hicn4_iface_output_format_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN (hicn_iface_ip4_output_error_strings),
- .error_strings = hicn_iface_ip4_output_error_strings,
- .n_next_nodes = HICN_IFACE_IP4_OUTPUT_N_NEXT,
+ .n_errors = ARRAY_LEN (hicn4_iface_output_error_strings),
+ .error_strings = hicn4_iface_output_error_strings,
+ .n_next_nodes = HICN4_IFACE_OUTPUT_N_NEXT,
/* edit / add dispositions here */
.next_nodes =
{
- [HICN_IFACE_IP4_OUTPUT_NEXT_LOOKUP] = "ip4-lookup",
- [HICN_IFACE_IP4_OUTPUT_NEXT_ERROR_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"
},
};
/* *INDENT-ON* */
static uword
-hicn_iface_ip6_output_node_fn (vlib_main_t * vm,
+hicn6_iface_output_node_fn (vlib_main_t * vm,
vlib_node_runtime_t * node,
vlib_frame_t * frame)
{
@@ -873,12 +867,12 @@ hicn_iface_ip6_output_node_fn (vlib_main_t * vm,
/* packet trace format function */
static u8 *
-hicn_iface_ip6_output_format_trace (u8 * s, va_list * args)
+hicn6_iface_output_format_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 *);
- hicn_iface_ip6_output_trace_t *t =
- va_arg (*args, hicn_iface_ip6_output_trace_t *);
+ hicn6_iface_output_trace_t *t =
+ va_arg (*args, hicn6_iface_output_trace_t *);
s =
format (s, "IFACE_IP6_OUTPUT: pkt: %d, sw_if_index %d, next index %d\n%U",
@@ -891,21 +885,23 @@ hicn_iface_ip6_output_format_trace (u8 * s, va_list * args)
* Node registration for the interest forwarder node
*/
/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (hicn_iface_ip6_output_node) =
+VLIB_REGISTER_NODE (hicn6_iface_output_node) =
{
- .function = hicn_iface_ip6_output_node_fn,
- .name = "hicn-iface-ip6-output",
+ .function = hicn6_iface_output_node_fn,
+ .name = "hicn6-iface-output",
.vector_size = sizeof (u32),
- .format_trace = hicn_iface_ip6_output_format_trace,
+ .format_trace = hicn6_iface_output_format_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN (hicn_iface_ip6_output_error_strings),
- .error_strings = hicn_iface_ip6_output_error_strings,
- .n_next_nodes = HICN_IFACE_IP6_OUTPUT_N_NEXT,
+ .n_errors = ARRAY_LEN (hicn6_iface_output_error_strings),
+ .error_strings = hicn6_iface_output_error_strings,
+ .n_next_nodes = HICN6_IFACE_OUTPUT_N_NEXT,
/* edit / add dispositions here */
.next_nodes =
{
- [HICN_IFACE_IP6_OUTPUT_NEXT_LOOKUP] = "ip6-lookup",
- [HICN_IFACE_IP6_OUTPUT_NEXT_ERROR_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"
+
},
};
/* *INDENT-ON* */
diff --git a/hicn-plugin/src/faces/iface_node.h b/hicn-plugin/src/faces/iface_node.h
new file mode 100644
index 000000000..1a7c4291b
--- /dev/null
+++ b/hicn-plugin/src/faces/iface_node.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2020 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_IFACE_NODE_H__
+#define __HICN_IFACE_NODE_H__
+
+#include <vlib/vlib.h>
+#include <vnet/vnet.h>
+
+/**
+ * @file iface_node.h
+ *
+ * Implements the input and output iface nodes. Input iface nodes
+ * process incoming interests while output face nodes process outgoing
+ * data packets.
+ *
+ * Input iface nodes follow ip-lookup nodes and their purpose
+ * is to create (or retrieve if already existing) the list incoming face
+ * for each the interest packet.
+ * The following node to the input iface nodes is the hicn-interest-pcslookup.
+ * Output iface nodes follow the hicn-data-fwd and the hicn-interest-hitcs nodes and
+ * they perform the dst nat on each data packet. The node following the
+ * output face nodes depends on the adjacency type. In case of ip, the following
+ * node is the ip4/6-lookup, in case of tunnels the next node is the one implementing
+ * the tunnel encapsulation (udp-encap, mpls, etc).
+ */
+
+
+/**
+ * @brief Initialize the ip iface module
+ */
+void hicn_iface_init (vlib_main_t * vm);
+
+#endif // __HICN_IFACE_IP_NODE_H__
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/hicn-plugin/src/faces/ip/dpo_ip.c b/hicn-plugin/src/faces/ip/dpo_ip.c
deleted file mode 100644
index d05fec1a0..000000000
--- a/hicn-plugin/src/faces/ip/dpo_ip.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2017-2019 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 "dpo_ip.h"
-
-mhash_t hicn_face_ip_local_hashtb;
-mhash_t hicn_face_ip_remote_hashtb;
-dpo_type_t hicn_face_ip_type;
-
-hicn_face_ip_vec_t * hicn_vec_pool;
-
-const static char *const hicn_face_ip4dpoi_nodes[] = {
- "hicn-face-ip4-input",
- "hicn-face-ip4-output",
- "hicn-iface-ip4-input",
- "hicn-iface-ip4-output",
- NULL,
-};
-
-const static char *const hicn_face_ip6dpoi_nodes[] = {
- "hicn-face-ip6-input",
- "hicn-face-ip6-output",
- "hicn-iface-ip6-input",
- "hicn-iface-ip6-output",
- NULL,
-};
-
-const static char *const *const hicn_ip_nodes[DPO_PROTO_NUM] = {
- [DPO_PROTO_IP4] = hicn_face_ip4dpoi_nodes,
- [DPO_PROTO_IP6] = hicn_face_ip6dpoi_nodes
-};
-
-const static dpo_vft_t hicn_face_ip_vft = {
- .dv_lock = hicn_face_lock,
- .dv_unlock = hicn_face_unlock,
- .dv_format = format_hicn_face_ip,
-};
-
-/* Must be executed after all the strategy nodes are created */
-void
-hicn_dpo_ip_module_init (void)
-{
- mhash_init (&hicn_face_ip_local_hashtb,
- sizeof (hicn_face_ip_input_faces_t) /* value */ ,
- sizeof (hicn_face_ip_key_t) /* key */ );
- mhash_init (&hicn_face_ip_remote_hashtb,
- sizeof (hicn_face_id_t) /* value */ ,
- sizeof (hicn_face_ip_key_t) /* key */ );
-
- pool_alloc(hicn_vec_pool, 100);
-
- /*
- * How much useful is the following registration?
- * So far it seems that we need it only for setting the dpo_type.
- */
- hicn_face_ip_type =
- dpo_register_new_type (&hicn_face_ip_vft, hicn_ip_nodes);
-}
-
-void
-hicn_dpo_ip_create_from_face (hicn_face_t * face, dpo_id_t * dpo,
- u16 dpoi_next_node)
-{
- hicn_face_id_t face_dpoi_id = hicn_dpoi_get_index (face);
- hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data;
- dpo_set (dpo, face->shared.face_type,
- ip46_address_is_ip4 (&ip_face->local_addr) ? DPO_PROTO_IP4 :
- DPO_PROTO_IP6, face_dpoi_id);
- dpo->dpoi_next_node = dpoi_next_node;
-}
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/hicn-plugin/src/faces/ip/dpo_ip.h b/hicn-plugin/src/faces/ip/dpo_ip.h
deleted file mode 100644
index c893c8be4..000000000
--- a/hicn-plugin/src/faces/ip/dpo_ip.h
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Copyright (c) 2017-2019 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_DPO_IP_H__
-#define __HICN_DPO_IP_H__
-
-#include <vnet/vnet.h>
-#include <vnet/ip/ip4_packet.h>
-
-#include "face_ip.h"
-#include "../face.h"
-
-/**
- * @brief Initialize the internal structures of the dpo ip face module.
- */
-void hicn_dpo_ip_module_init (void);
-
-
-/**
- * @brief Retrieve a vector of faces from the ip4 local address and returns its index.
- *
- * @param vec: Result of the lookup. If no face exists for the local address vec = NULL
- * @param hicnb_flags: Flags that indicate whether the face is an application
- * face or not
- * @param local_addr: Ip v4 local address of the face
- * @param sw_if: software interface id of the face
- *
- * @result HICN_ERROR_FACE_NOT_FOUND if the face does not exist, otherwise HICN_ERROR_NONE.
- */
-always_inline int
-hicn_dpo_ip4_lock_from_local (dpo_id_t * dpo,
- u32 * in_faces_vec_id,
- u8 * hicnb_flags,
- const ip4_address_t * local_addr, u32 sw_if)
-{
- dpo->dpoi_type = DPO_FIRST;
- dpo->dpoi_proto = DPO_PROTO_NONE;
- dpo->dpoi_index = INDEX_INVALID;
- dpo->dpoi_next_node = 0;
- hicn_face_ip_input_faces_t *in_faces_vec =
- hicn_face_ip4_get_vec (local_addr, sw_if, &hicn_face_ip_local_hashtb);
-
- if (PREDICT_FALSE (in_faces_vec == NULL))
- return HICN_ERROR_FACE_NOT_FOUND;
-
- *in_faces_vec_id = in_faces_vec->vec_id;
- hicn_face_t *face = hicn_dpoi_get_from_idx (in_faces_vec->face_id);
-
- *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
- *hicnb_flags |=
- (face->shared.flags & HICN_FACE_FLAGS_APPFACE_PROD) >>
- HICN_FACE_FLAGS_APPFACE_PROD_BIT;
-
- dpo_set (dpo, hicn_face_ip_type, DPO_PROTO_IP4, in_faces_vec->face_id);
- dpo->dpoi_next_node = ~0;
- dpo_unlock (dpo);
-
- return HICN_ERROR_NONE;
-}
-
-/**
- * @brief Retrieve a face from the ip6 local address and returns its dpo. This
- * method adds a lock on the face state.
- *
- * @param dpo: Result of the lookup. If the face doesn't exist dpo = NULL
- * @param hicnb_flags: Flags that indicate whether the face is an application
- * face or not
- * @param local_addr: Ip v6 local address of the face
- * @param sw_if: software interface id of the face
- *
- * @result HICN_ERROR_FACE_NOT_FOUND if the face does not exist, otherwise HICN_ERROR_NONE.
- */
-always_inline int
-hicn_dpo_ip6_lock_from_local (dpo_id_t * dpo,
- u32 * in_faces_vec_id,
- u8 * hicnb_flags,
- const ip6_address_t * local_addr, u32 sw_if)
-{
- dpo->dpoi_type = DPO_FIRST;
- dpo->dpoi_proto = DPO_PROTO_NONE;
- dpo->dpoi_index = INDEX_INVALID;
- dpo->dpoi_next_node = 0;
- hicn_face_ip_input_faces_t *in_faces_vec =
- hicn_face_ip6_get_vec (local_addr, sw_if, &hicn_face_ip_local_hashtb);
-
- if (PREDICT_FALSE (in_faces_vec == NULL))
- return HICN_ERROR_FACE_NOT_FOUND;
-
- *in_faces_vec_id = in_faces_vec->vec_id;
- hicn_face_t *face = hicn_dpoi_get_from_idx (in_faces_vec->face_id);
-
- *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
- *hicnb_flags |=
- (face->shared.flags & HICN_FACE_FLAGS_APPFACE_PROD) >>
- HICN_FACE_FLAGS_APPFACE_PROD_BIT;
-
- dpo_set (dpo, hicn_face_ip_type, DPO_PROTO_IP6, in_faces_vec->face_id);
- dpo->dpoi_next_node = ~0;
- dpo_unlock (dpo);
-
- return HICN_ERROR_NONE;
-}
-
-
-/**
- * @brief Retrieve, or create if it doesn't exist, a face from the ip6 local
- * address and returns its dpo. This method adds a lock on the face state.
- *
- * @param dpo: Result of the lookup
- * @param hicnb_flags: Flags that indicate whether the face is an application
- * face or not
- * @param local_addr: Ip v4 local address of the face
- * @param remote_addr: Ip v4 remote address of the face
- * @param sw_if: software interface id of the face
- * @param node_index: vlib edge index to use in the packet processing
- */
-always_inline void
-hicn_dpo_ip4_add_and_lock_from_remote (dpo_id_t * dpo,
- u8 * hicnb_flags,
- const ip4_address_t * local_addr,
- const ip4_address_t * remote_addr,
- u32 sw_if, u32 node_index)
-{
- dpo->dpoi_type = DPO_FIRST;
- dpo->dpoi_proto = DPO_PROTO_NONE;
- dpo->dpoi_index = INDEX_INVALID;
- dpo->dpoi_next_node = 0;
- /*All (complete) faces are indexed by remote addess as well */
- hicn_face_t *face =
- hicn_face_ip4_get (remote_addr, sw_if, &hicn_face_ip_remote_hashtb);
-
- if (face == NULL)
- {
- hicn_face_id_t dpoi_index;
- ip46_address_t local_addr46 = to_ip46 (0, (u8 *) local_addr);
- ip46_address_t remote_addr46 = to_ip46 (0, (u8 *) remote_addr);
- hicn_iface_ip_add (&local_addr46, &remote_addr46, sw_if, &dpoi_index);
-
- *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
-
- dpo_set (dpo, hicn_face_ip_type, DPO_PROTO_IP4, dpoi_index);
- dpo->dpoi_next_node = node_index;
- dpo_unlock (dpo);
-
- return;
- }
-
- /* Code replicated on purpose */
- *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
- *hicnb_flags |=
- (face->shared.flags & HICN_FACE_FLAGS_APPFACE_PROD) >>
- HICN_FACE_FLAGS_APPFACE_PROD_BIT;
-
- hicn_face_id_t dpoi_index = hicn_dpoi_get_index (face);
- dpo_set (dpo, hicn_face_ip_type, DPO_PROTO_IP4, dpoi_index);
- dpo->dpoi_next_node = node_index;
- dpo_unlock (dpo);
-}
-
-/**
- * @brief Retrieve, or create if it doesn't exist, a face from the ip6 local
- * address and returns its dpo. This method adds a lock on the face state.
- *
- * @param dpo: Result of the lookup
- * @param hicnb_flags: Flags that indicate whether the face is an application
- * face or not
- * @param local_addr: Ip v6 local address of the face
- * @param remote_addr: Ip v6 remote address of the face
- * @param sw_if: software interface id of the face
- * @param node_index: vlib edge index to use in the packet processing
- */
-always_inline void
-hicn_dpo_ip6_add_and_lock_from_remote (dpo_id_t * dpo,
- u8 * hicnb_flags,
- const ip6_address_t * local_addr,
- const ip6_address_t * remote_addr,
- u32 sw_if, u32 node_index)
-{
- dpo->dpoi_type = DPO_FIRST;
- dpo->dpoi_proto = DPO_PROTO_NONE;
- dpo->dpoi_index = INDEX_INVALID;
- dpo->dpoi_next_node = 0;
- /*All (complete) faces are indexed by remote addess as well */
- hicn_face_t *face =
- hicn_face_ip6_get (remote_addr, sw_if, &hicn_face_ip_remote_hashtb);
-
- if (face == NULL)
- {
- hicn_face_id_t dpoi_index;
- hicn_iface_ip_add ((ip46_address_t *) local_addr,
- (ip46_address_t *) remote_addr, sw_if, &dpoi_index);
-
- *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
-
- dpo_set (dpo, hicn_face_ip_type, DPO_PROTO_IP4, dpoi_index);
- dpo->dpoi_next_node = node_index;
- dpo_unlock (dpo);
-
- return;
- }
- /* Code replicated on purpose */
- *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
- *hicnb_flags |=
- (face->shared.flags & HICN_FACE_FLAGS_APPFACE_PROD) >>
- HICN_FACE_FLAGS_APPFACE_PROD_BIT;
-
- index_t dpoi_index = hicn_dpoi_get_index (face);
- dpo_set (dpo, hicn_face_ip_type, DPO_PROTO_IP6, dpoi_index);
- dpo->dpoi_next_node = node_index;
- dpo_unlock (dpo);
-}
-
-
-/* /\** */
-/* * @brief Create an ip face and its corresponding dpo. Meant to be used for the */
-/* * control plane. */
-/* * */
-/* * @param dpo: Data plane object that point to the face created. */
-/* * @param local_addr: Ip v4 local address of the face */
-/* * @param remote_addr: Ip v4 remote address of the face */
-/* * @param sw_if: software interface id of the face */
-/* * @param adj: Ip adjacency corresponding to the remote address in the face */
-/* * @param node_index: vlib edge index to use in the packet processing */
-/* * @param flags: Flags of the face */
-/* * @param face_id: Identifier for the face (dpoi_index) */
-/* * @return HICN_ERROR_FACE_ALREADY_CREATED if the face exists, otherwise HICN_ERROR_NONE */
-/* *\/ */
-/* int hicn_dpo_ip4_create (dpo_id_t * dpo, */
-/* const ip4_address_t * local_addr, */
-/* const ip4_address_t * remote_addr, */
-/* u32 sw_if, */
-/* adj_index_t adj, */
-/* u32 node_index, */
-/* hicn_face_flags_t flags, hicn_face_id_t * face_id); */
-
-/* /\** */
-/* * @brief Create an ip face and its corresponding dpo. Meant to be used for the */
-/* * control plane. */
-/* * */
-/* * @param dpo: Data plane object that point to the face created. */
-/* * @param local_addr: Ip v6 local address of the face */
-/* * @param remote_addr: Ip v6 remote address of the face */
-/* * @param sw_if: software interface id of the face */
-/* * @param adj: Ip adjacency corresponding to the remote address in the face */
-/* * @param node_index: vlib edge index to use in the packet processing */
-/* * @param flags: Flags of the face */
-/* * @param face_id: Identifier for the face (dpoi_index) */
-/* * @return HICN_ERROR_FACE_ALREADY_CREATED if the face exists, otherwise HICN_ERROR_NONE */
-/* *\/ */
-/* int hicn_dpo_ip6_create (dpo_id_t * dpo, */
-/* const ip6_address_t * local_addr, */
-/* const ip6_address_t * remote_addr, */
-/* u32 sw_if, */
-/* adj_index_t adj, */
-/* u32 node_index, */
-/* hicn_face_flags_t flags, hicn_face_id_t * face_id); */
-
-/**
- * @brief Create a dpo from an ip face
- *
- * @param face Face from which to create the dpo
- * @param dpoi_next_node Edge index that connects a node to the iface or face nodes
- * @return the dpo
- */
-void hicn_dpo_ip_create_from_face (hicn_face_t * face, dpo_id_t * dpo,
- u16 dpoi_next_node);
-
-#endif // __HICN_DPO_IP_H__
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/hicn-plugin/src/faces/ip/face_ip.c b/hicn-plugin/src/faces/ip/face_ip.c
deleted file mode 100644
index a2fe069ed..000000000
--- a/hicn-plugin/src/faces/ip/face_ip.c
+++ /dev/null
@@ -1,571 +0,0 @@
-/*
- * Copyright (c) 2017-2019 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 <vnet/adj/adj_midchain.h>
-#include <vnet/adj/adj.h>
-
-#include "face_ip.h"
-#include "face_ip_node.h"
-#include "dpo_ip.h"
-#include "../../strategy_dpo_manager.h"
-#include "../face.h"
-#include "../../cache_policies/cs_lru.h"
-#include "../../infra.h"
-#include "../../hicn.h"
-#include "../app/face_prod.h"
-#include "../app/face_cons.h"
-
-#include "../../mapme.h" // HICN_MAPME_EVENT_*
-#include "../../mapme_eventmgr.h" // hicn_mapme_eventmgr_process_node
-
-extern vlib_node_registration_t hicn_mapme_eventmgr_process_node;
-
-u32 strategy_face_ip4_vlib_edge;
-u32 strategy_face_ip6_vlib_edge;
-
-void
-hicn_face_ip_init (vlib_main_t * vm)
-{
- int strategy_nodes_n = hicn_strategy_get_all_available ();
-
- /* Default Strategy has index 0 and it always exists */
- strategy_face_ip4_vlib_edge = vlib_node_add_next (vm,
- hicn_strategy_node.index,
- hicn_face_ip4_output_node.index);
-
- strategy_face_ip6_vlib_edge = vlib_node_add_next (vm,
- hicn_strategy_node.index,
- hicn_face_ip6_output_node.index);
- /*
- * Create and edge between al the other strategy nodes and the
- * ip_encap nodes.
- */
- for (int i = 1; i < strategy_nodes_n; i++)
- {
- u32 temp_index4 = vlib_node_add_next (vm,
- hicn_strategy_node.index,
- hicn_face_ip4_output_node.index);
- u32 temp_index6 = vlib_node_add_next (vm,
- hicn_strategy_node.index,
- hicn_face_ip6_output_node.index);
- ASSERT (temp_index4 == strategy_face_ip4_vlib_edge);
- ASSERT (temp_index6 == strategy_face_ip6_vlib_edge);
- }
-
- u32 temp_index4 = vlib_node_add_next (vm,
- hicn_interest_hitpit_node.index,
- hicn_face_ip4_output_node.index);
- u32 temp_index6 = vlib_node_add_next (vm,
- hicn_interest_hitpit_node.index,
- hicn_face_ip6_output_node.index);
-
- ASSERT (temp_index4 == strategy_face_ip4_vlib_edge);
- ASSERT (temp_index6 == strategy_face_ip6_vlib_edge);
-
-
- hicn_dpo_ip_module_init ();
-
- register_face_type (hicn_face_ip_type, &ip_vft, "ip");
-}
-
-int
-hicn_face_ip_del (hicn_face_id_t face_id)
-{
- hicn_face_t *face = hicn_dpoi_get_from_idx (face_id);
- hicn_face_ip_t *face_ip = (hicn_face_ip_t *) face->data;
- hicn_face_ip_key_t key;
- hicn_face_ip_key_t old_key;
- hicn_face_ip_key_t old_key2;
-
- if (ip46_address_is_ip4 (&face_ip->local_addr))
- {
- hicn_face_ip4_get_key (&(face_ip->local_addr.ip4), face->shared.sw_if,
- &key);
- hicn_face_ip_input_faces_t *in_faces_vec =
- hicn_face_ip4_get_vec (&(face_ip->local_addr.ip4), face->shared.sw_if,
- &hicn_face_ip_local_hashtb);
- if (in_faces_vec != NULL)
- {
- hicn_face_ip_vec_t *vec =
- pool_elt_at_index (hicn_vec_pool, in_faces_vec->vec_id);
- u32 index_face = vec_search (*vec, face_id);
- vec_del1 (*vec, index_face);
-
- if (vec_len (*vec) == 0)
- {
- pool_put_index (hicn_vec_pool, in_faces_vec->vec_id);
- mhash_unset (&hicn_face_ip_local_hashtb, &key,
- (uword *) & old_key);
- vec_free (*vec);
- }
- else
- {
- /* Check if the face we are deleting is the preferred one. */
- /* If so, repleace with another. */
- if (in_faces_vec->face_id == face_id)
- {
- in_faces_vec->face_id = (*vec)[0];
- }
- }
- hicn_face_ip4_get_key (&(face_ip->remote_addr.ip4),
- face->shared.sw_if, &key);
- mhash_unset (&hicn_face_ip_remote_hashtb, &key,
- (uword *) & old_key2);
- }
- }
- else
- {
- hicn_face_ip6_get_key (&(face_ip->local_addr.ip6), face->shared.sw_if,
- &key);
-
- hicn_face_ip_input_faces_t *in_faces_vec =
- hicn_face_ip6_get_vec (&(face_ip->local_addr.ip6), face->shared.sw_if,
- &hicn_face_ip_local_hashtb);
- if (in_faces_vec != NULL)
- {
- hicn_face_ip_vec_t *vec =
- pool_elt_at_index (hicn_vec_pool, in_faces_vec->vec_id);
- u32 index_face = vec_search (*vec, face_id);
- vec_del1 (*vec, index_face);
-
- if (vec_len (*vec) == 0)
- {
- pool_put (hicn_vec_pool, vec);
- mhash_unset (&hicn_face_ip_local_hashtb, &key,
- (uword *) & old_key);
- vec_free (*vec);
- }
- else
- {
- /* Check if the face we are deleting is the preferred one. */
- /* If so, repleace with another. */
- if (in_faces_vec->face_id == face_id)
- {
- in_faces_vec->face_id = (*vec)[0];
- }
- }
- hicn_face_ip6_get_key (&(face_ip->remote_addr.ip6),
- face->shared.sw_if, &key);
- mhash_unset (&hicn_face_ip_remote_hashtb, &key,
- (uword *) & old_key);
- }
- }
- return hicn_face_del (face_id);
-}
-
-/**
- * @brief Helper for handling midchain adjacencies
- */
-void
-face_midchain_fixup_t (vlib_main_t * vm,
- const struct ip_adjacency_t_ *adj,
- vlib_buffer_t * b0, const void *data)
-{
- vnet_buffer (b0)->sw_if_index[VLIB_TX] = 0;
-};
-
-/**
- * @brief Build a rewrite string for the face.
- */
-static u8 *
-face_build_rewrite_i (void)
-{
- /*
- * passing the adj code a NULL rewrite means 'i don't have one cos
- * t'other end is unresolved'. That's not the case here. For the mpls
- * tunnel there are just no bytes of encap to apply in the adj. We'll impose
- * the label stack once we choose a path. So return a zero length rewrite.
- */
- u8 *rewrite = NULL;
-
- vec_validate (rewrite, 0);
- vec_reset_length (rewrite);
-
- return (rewrite);
-}
-
-always_inline int
-hicn_face_ip_find_adj (const ip46_address_t * remote_addr,
- int sw_if, adj_index_t * adj)
-{
- fib_prefix_t fib_pfx;
- fib_node_index_t fib_entry_index;
- fib_prefix_from_ip46_addr (remote_addr, &fib_pfx);
- fib_pfx.fp_len = ip46_address_is_ip4 (remote_addr) ? 32 : 128;
- vnet_link_t link_type =
- ip46_address_is_ip4 (&fib_pfx.fp_addr) ? VNET_LINK_IP4 : VNET_LINK_IP6;
- *adj = adj_nbr_find (fib_pfx.fp_proto, link_type, &fib_pfx.fp_addr, sw_if);
-
- if (*adj == ADJ_INDEX_INVALID)
- {
- u32 fib_index = fib_table_find_or_create_and_lock (fib_pfx.fp_proto,
- HICN_FIB_TABLE,
- FIB_SOURCE_PRIORITY_HI);
-
- fib_entry_index = fib_table_lookup (fib_index, &fib_pfx);
-
- if (fib_entry_index == (FIB_NODE_INDEX_INVALID))
- return HICN_ERROR_FACE_IP_ADJ_NOT_FOUND;
-
- *adj = fib_entry_get_adj (fib_entry_index);
- ip_adjacency_t *temp = NULL;
- if (*adj != ~0)
- temp = adj_get (*adj);
-
- if (temp == NULL || temp->lookup_next_index <= IP_LOOKUP_NEXT_MIDCHAIN)
- {
- if (sw_if != ~0)
- *adj =
- adj_nbr_add_or_lock (fib_pfx.fp_proto, link_type, remote_addr,
- sw_if);
- else
- return HICN_ERROR_FACE_IP_ADJ_NOT_FOUND;
- }
- else
- {
- adj_nbr_midchain_update_rewrite (*adj, &face_midchain_fixup_t, NULL,
- ADJ_FLAG_NONE,
- face_build_rewrite_i ());
- adj_midchain_delegate_stack (*adj, fib_index, &fib_pfx);
- }
- }
-
- return HICN_ERROR_NONE;
-}
-
-/*
- * Utility that adds a new face cache entry. For the moment we assume that
- * the ip_adjacency has already been set up.
- */
-int
-hicn_face_ip_add (const ip46_address_t * local_addr,
- const ip46_address_t * remote_addr,
- int sw_if, hicn_face_id_t * pfaceid, u8 is_app_prod)
-{
- dpo_proto_t dpo_proto;
-
- /* Check if we found at least one ip address */
- if (ip46_address_is_zero (remote_addr))
- return HICN_ERROR_FACE_NO_GLOBAL_IP;
-
- hicn_face_flags_t flags = (hicn_face_flags_t) 0;
- flags |= HICN_FACE_FLAGS_FACE;
-
- hicn_face_t *face;
- if (ip46_address_is_ip4 (local_addr))
- {
- face =
- hicn_face_ip4_get (&(remote_addr->ip4), sw_if,
- &hicn_face_ip_remote_hashtb);
-
- /* If remote matches the face we need to check if it is an incomplete face */
- if (face == NULL)
- {
- hicn_iface_ip_add (local_addr, remote_addr, sw_if, pfaceid);
- face = hicn_dpoi_get_from_idx (*pfaceid);
- }
- else
- {
- *pfaceid = hicn_dpoi_get_index (face);
- }
-
- if (!(face->shared.flags & HICN_FACE_FLAGS_IFACE))
- return HICN_ERROR_FACE_ALREADY_CREATED;
-
- hicn_face_ip_key_t key;
- hicn_face_ip4_get_key (&(local_addr->ip4), sw_if, &key);
-
- hicn_face_ip_input_faces_t *in_faces =
- hicn_face_ip4_get_vec (&(local_addr->ip4), sw_if,
- &hicn_face_ip_local_hashtb);
-
- if (in_faces == NULL)
- {
- adj_index_t adj;
- int ret = hicn_face_ip_find_adj (remote_addr, sw_if, &adj);
- if (ret != HICN_ERROR_NONE)
- return ret;
-
- hicn_face_ip_input_faces_t in_faces_temp;
- hicn_face_ip_vec_t *vec;
- pool_get (hicn_vec_pool, vec);
- *vec = vec_new (hicn_face_ip_vec_t, 0);
- u32 index = vec - hicn_vec_pool;
- in_faces_temp.vec_id = index;
- vec_add1 (*vec, *pfaceid);
-
- hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data;
- clib_memcpy (&ip_face->local_addr, local_addr,
- sizeof (ip4_address_t));
- clib_memcpy (&ip_face->remote_addr, remote_addr,
- sizeof (ip4_address_t));
- face->shared.sw_if = sw_if;
- face->shared.flags = flags;
- face->shared.adj = adj;
-
- dpo_proto = DPO_PROTO_IP4;
-
- in_faces_temp.face_id = *pfaceid;
-
- mhash_set_mem (&hicn_face_ip_local_hashtb, &key,
- (uword *) & in_faces_temp, 0);
- }
- else
- {
- hicn_face_ip_vec_t *vec =
- pool_elt_at_index (hicn_vec_pool, in_faces->vec_id);
-
- /* */
- if (vec_search (*vec, *pfaceid) != ~0)
- return HICN_ERROR_FACE_ALREADY_CREATED;
-
- adj_index_t adj;
- int ret = hicn_face_ip_find_adj (remote_addr, sw_if, &adj);
- if (ret != HICN_ERROR_NONE)
- return ret;
-
- vec_add1 (*vec, *pfaceid);
-
- hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data;
- clib_memcpy (&ip_face->local_addr, local_addr,
- sizeof (ip4_address_t));
- clib_memcpy (&ip_face->remote_addr, remote_addr,
- sizeof (ip4_address_t));
- face->shared.sw_if = sw_if;
- face->shared.flags = flags;
- face->shared.adj = adj;
-
- dpo_proto = DPO_PROTO_IP4;
-
- mhash_set_mem (&hicn_face_ip_local_hashtb, &key, (uword *) in_faces,
- 0);
-
- /* If the face is an application producer face, we set it as the preferred incoming face. */
- /* This is required to handle the CS separation, and the push api in a lightway */
- if (is_app_prod)
- {
- in_faces->face_id = *pfaceid;
- }
- }
- }
- else
- {
- face =
- hicn_face_ip6_get (&(remote_addr->ip6), sw_if,
- &hicn_face_ip_remote_hashtb);
-
- /* If remote matches the face is a iface */
- if (face == NULL)
- {
- hicn_iface_ip_add (local_addr, remote_addr, sw_if, pfaceid);
- face = hicn_dpoi_get_from_idx (*pfaceid);
- }
- else
- {
- *pfaceid = hicn_dpoi_get_index (face);
- }
-
- if (!(face->shared.flags & HICN_FACE_FLAGS_IFACE))
- return HICN_ERROR_FACE_ALREADY_CREATED;
-
- hicn_face_ip_key_t key;
- hicn_face_ip6_get_key (&(local_addr->ip6), sw_if, &key);
-
- hicn_face_ip_input_faces_t *in_faces =
- hicn_face_ip6_get_vec (&(local_addr->ip6), sw_if,
- &hicn_face_ip_local_hashtb);
-
- if (in_faces == NULL)
- {
- adj_index_t adj;
- int ret = hicn_face_ip_find_adj (remote_addr, sw_if, &adj);
- if (ret != HICN_ERROR_NONE)
- return ret;
-
- hicn_face_ip_input_faces_t in_faces_temp;
- hicn_face_ip_vec_t *vec;
- pool_get (hicn_vec_pool, vec);
- vec_alloc (*vec, 1);
- u32 index = vec - hicn_vec_pool;
- in_faces_temp.vec_id = index;
- vec_add1 (*vec, *pfaceid);
-
- hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data;
- clib_memcpy (&ip_face->local_addr, local_addr,
- sizeof (ip6_address_t));
- clib_memcpy (&ip_face->remote_addr, remote_addr,
- sizeof (ip6_address_t));
- face->shared.sw_if = sw_if;
- face->shared.flags = flags;
- face->shared.adj = adj;
-
- dpo_proto = DPO_PROTO_IP6;
-
- in_faces_temp.face_id = *pfaceid;
-
- mhash_set_mem (&hicn_face_ip_local_hashtb, &key,
- (uword *) & in_faces_temp, 0);
- }
- else
- {
- hicn_face_ip_vec_t *vec =
- pool_elt_at_index (hicn_vec_pool, in_faces->vec_id);
-
- /* */
- if (vec_search (*vec, *pfaceid) != ~0)
- return HICN_ERROR_FACE_ALREADY_CREATED;
-
- adj_index_t adj;
- int ret = hicn_face_ip_find_adj (remote_addr, sw_if, &adj);
- if (ret != HICN_ERROR_NONE)
- return ret;
-
- vec_add1 (*vec, *pfaceid);
-
- hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data;
- clib_memcpy (&ip_face->local_addr, local_addr,
- sizeof (ip6_address_t));
- clib_memcpy (&ip_face->remote_addr, remote_addr,
- sizeof (ip6_address_t));
- face->shared.sw_if = sw_if;
- face->shared.flags = flags;
- face->shared.adj = adj;
-
- dpo_proto = DPO_PROTO_IP6;
-
- mhash_set_mem (&hicn_face_ip_local_hashtb, &key, (uword *) in_faces,
- 0);
-
- /* If the face is an application producer face, we set it as the preferred incoming face. */
- /* This is required to handle the CS separation, and the push api in a lightway */
- if (is_app_prod)
- {
- in_faces->face_id = *pfaceid;
- }
- }
- }
-
- retx_t *retx = vlib_process_signal_event_data (vlib_get_main (),
- hicn_mapme_eventmgr_process_node.index,
- HICN_MAPME_EVENT_FACE_ADD, 1,
- sizeof (retx_t));
-
- /* *INDENT-OFF* */
- *retx = (retx_t)
- {
- .prefix = 0,
- .dpo = (dpo_id_t)
- {
- .dpoi_type = hicn_face_ip_type,
- .dpoi_proto = dpo_proto,
- .dpoi_next_node = 0,
- .dpoi_index = *pfaceid,
- }
- };
- /* *INDENT-ON* */
-
- return HICN_ERROR_NONE;
-}
-
-u8 *
-format_hicn_face_ip (u8 * s, va_list * args)
-{
- index_t index = va_arg (*args, index_t);
- CLIB_UNUSED (u32 indent) = va_arg (*args, u32);
- hicn_face_t *face;
- hicn_face_ip_t *ip_face;
- ip_adjacency_t *adj;
- vnet_main_t *vnm = vnet_get_main ();
-
- face = hicn_dpoi_get_from_idx (index);
- ip_face = (hicn_face_ip_t *) face->data;
-
- if (face->shared.flags & HICN_FACE_FLAGS_FACE)
- {
- ASSERT (face->shared.adj != (adj_index_t) ~ 0);
- adj = adj_get (face->shared.adj);
-
- hicn_face_id_t face_id = hicn_dpoi_get_index (face);
- s = format (s, "%U Face %d: ", format_white_space, indent, face_id);
- s = format (s, "type IP local %U ",
- format_ip46_address, &ip_face->local_addr, IP46_TYPE_ANY);
- s =
- format (s, "remote %U ", format_ip46_address, &ip_face->remote_addr,
- IP46_TYPE_ANY);
- s = format (s, "%U", format_vnet_link, adj->ia_link);
-
- vnet_sw_interface_t *sw_int =
- vnet_get_sw_interface_or_null (vnm, face->shared.sw_if);
- if (sw_int != NULL)
- s = format (s, " dev %U", format_vnet_sw_interface_name, vnm, sw_int);
-
-
- if ((face->shared.flags & HICN_FACE_FLAGS_APPFACE_PROD))
- s = format (s, " %U", format_hicn_face_prod, face_id, 0);
- else if ((face->shared.flags & HICN_FACE_FLAGS_APPFACE_CONS))
- s = format (s, " %U", format_hicn_face_cons, face_id, 0);
-
- if ((face->shared.flags & HICN_FACE_FLAGS_DELETED))
- s = format (s, " (deleted)");
- }
- else
- {
- hicn_face_id_t face_id = hicn_dpoi_get_index (face);
- s = format (s, "%U iFace %d: ", format_white_space, indent, face_id);
- s = format (s, "type IP local %U remote %U",
- format_ip46_address, &ip_face->local_addr, IP46_TYPE_ANY,
- format_ip46_address, &ip_face->remote_addr, IP46_TYPE_ANY);
-
- vnet_sw_interface_t *sw_int =
- vnet_get_sw_interface_or_null (vnm, face->shared.sw_if);
- if (sw_int != NULL)
- s = format (s, " dev %U", format_vnet_sw_interface_name, vnm, sw_int);
-
- if ((face->shared.flags & HICN_FACE_FLAGS_APPFACE_PROD))
- s = format (s, " %U", format_hicn_face_prod, face_id, 0);
- else if ((face->shared.flags & HICN_FACE_FLAGS_APPFACE_CONS))
- s = format (s, " %U", format_hicn_face_cons, face_id, 0);
-
- if ((face->shared.flags & HICN_FACE_FLAGS_DELETED))
- s = format (s, " (deleted)");
- }
-
- return s;
-}
-
-void
-hicn_face_ip_get_dpo (hicn_face_t * face, dpo_id_t * dpo)
-{
-
- hicn_face_ip_t *face_ip = (hicn_face_ip_t *) face->data;
- return hicn_dpo_ip_create_from_face (face, dpo,
- ip46_address_is_ip4
- (&face_ip->remote_addr) ?
- strategy_face_ip4_vlib_edge :
- strategy_face_ip6_vlib_edge);
-}
-
-hicn_face_vft_t ip_vft = {
- .format_face = format_hicn_face_ip,
- .hicn_face_del = hicn_face_ip_del,
- .hicn_face_get_dpo = hicn_face_ip_get_dpo,
-};
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/hicn-plugin/src/faces/ip/face_ip.h b/hicn-plugin/src/faces/ip/face_ip.h
deleted file mode 100644
index 74f3a83dc..000000000
--- a/hicn-plugin/src/faces/ip/face_ip.h
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * Copyright (c) 2017-2019 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_IP_H__
-#define __HICN_FACE_IP_H__
-
-#include <vlib/vlib.h>
-#include <vnet/vnet.h>
-#include "../face.h"
-#include "../../cache_policies/cs_policy.h"
-
-/**
- * @file
- *
- * @brief IP face
- *
- * A face is carried through nodes as a dpo. The face state is the object
- * pointed by the dpoi_index in the dpo_id_t (see
- * https://docs.fd.io/vpp/18.07/d0/d37/dpo_8h_source.html)
- */
-typedef struct hicn_ip_face_t_
-{
- /**
- * The headers to paint, in packet painting order
- */
- /* Local address of the interface sw_if */
- ip46_address_t local_addr;
-
- /* Remote address of neighbor */
- ip46_address_t remote_addr;
-
-} hicn_face_ip_t;
-
-/**
- * @bried vector of faces used to collect faces having the same local address
- *
- */
-typedef hicn_face_id_t *hicn_face_ip_vec_t;
-
-typedef struct hicn_ip_input_faces_s_
-{
- /* Vector of all possible input faces */
- u32 vec_id;
-
- /* Preferred face. If an prod_app face is in the vector it will be the preferred one. */
- /* It's not possible to have multiple prod_app face in the same vector, they would have */
- /* the same local address. Every prod_app face is a point-to-point face between the forwarder */
- /* and the application. */
- hicn_face_id_t face_id;
-
-} hicn_face_ip_input_faces_t;
-
-/**
- * Hash tables that indexes a face by local address. For fast lookup when an
- * data arrives.
- */
-extern mhash_t hicn_face_ip_local_hashtb;
-
-/**
- * Hash tables that indexes a face by remote address. For fast lookup when an
- * interest arrives.
- */
-extern mhash_t hicn_face_ip_remote_hashtb;
-
-/**
- * Pool containing the vector of possible incoming faces.
- */
-extern hicn_face_ip_vec_t *hicn_vec_pool;
-
-/**
- * Key definition for the mhash table. An ip face is uniquely identified by ip
- * address and the interface id. The ip address can correspond to the remote ip
- * address of the next hicn hop, or to the local address of the receiving
- * interface. The former is used to retrieve the incoming face when an interest
- * is received, the latter when the arring packet is a data.
- */
-typedef struct hicn_face_ip_key_s
-{
- ip46_address_t addr;
- u32 sw_if;
-} hicn_face_ip_key_t;
-
-
-extern hicn_face_type_t hicn_face_ip_type;
-extern hicn_face_vft_t ip_vft;
-
-/**
- * @brief Create the key object for the mhash. Fill in the key object with the
- * expected values.
- *
- * @param addr Local or remote ip v6 address of the face
- * @param sw_if interface associated to the face
- * @param key Pointer to an allocated hicn_face_ip_key_t object
- */
-always_inline void
-hicn_face_ip6_get_key (const ip6_address_t * addr,
- u32 sw_if, hicn_face_ip_key_t * key)
-{
- key->addr.ip6 = *addr;
- key->sw_if = sw_if;
-}
-
-
-/**
- * @brief Create the key object for the mhash. Fill in the key object with the
- * expected values.
- *
- * @param addr Local or remote ip v4 address of the face
- * @param sw_if interface associated to the face
- * @param key Pointer to an allocated hicn_face_ip_key_t object
- */
-always_inline void
-hicn_face_ip4_get_key (const ip4_address_t * addr,
- u32 sw_if, hicn_face_ip_key_t * key)
-{
- ip46_address_set_ip4 (&(key->addr), addr);
- key->sw_if = sw_if;
-}
-
-/**
- * @brief Get the dpoi from the ip v4 address. Does not add any lock.
- *
- * @param addr Ip v4 address used to create the key for the hash table.
- * @param sw_if Software interface id used to create the key for the hash table.
- * @param hashtb Hash table (remote or local) where to perform the lookup.
- *
- * @result Pointer to the face.
- */
-always_inline hicn_face_t *
-hicn_face_ip4_get (const ip4_address_t * addr, u32 sw_if, mhash_t * hashtb)
-{
- hicn_face_ip_key_t key;
-
- hicn_face_ip4_get_key (addr, sw_if, &key);
-
- hicn_face_id_t *dpoi_index = (hicn_face_id_t *) mhash_get (hashtb,
- &key);
-
- return dpoi_index == NULL ? NULL : hicn_dpoi_get_from_idx (*dpoi_index);
-}
-
-/**
- * @brief Get the vector of faces from the ip v4 address. Does not add any lock.
- *
- * @param addr Ip v4 address used to create the key for the hash table.
- * @param sw_if Software interface id used to create the key for the hash table.
- * @param hashtb Hash table (remote or local) where to perform the lookup.
- *
- * @result Pointer to the face.
- */
-always_inline hicn_face_ip_input_faces_t *
-hicn_face_ip4_get_vec (const ip4_address_t * addr, u32 sw_if,
- mhash_t * hashtb)
-{
- hicn_face_ip_key_t key;
-
- hicn_face_ip4_get_key (addr, sw_if, &key);
- return (hicn_face_ip_input_faces_t *) mhash_get (hashtb, &key);
-}
-
-/**
- * @brief Get the vector of faces from the ip v6 address. Does not add any lock.
- *
- * @param addr Ip v6 address used to create the key for the hash table.
- * @param sw_if Software interface id used to create the key for the hash table.
- * @param hashtb Hash table (remote or local) where to perform the lookup.
- *
- * @result Pointer to the face.
- */
-always_inline hicn_face_ip_input_faces_t *
-hicn_face_ip6_get_vec (const ip6_address_t * addr, u32 sw_if,
- mhash_t * hashtb)
-{
- hicn_face_ip_key_t key;
-
- hicn_face_ip6_get_key (addr, sw_if, &key);
- return (hicn_face_ip_input_faces_t *) mhash_get (hashtb, &key);
-}
-
-/**
- * @brief Get the dpoi from the ip v6 address. Does not add any lock.
- *
- * @param addr Ip v6 address used to create the key for the hash table.
- * @param sw_if Software interface id used to create the key for the hash table.
- * @param hashtb Hash table (remote or local) where to perform the lookup.
- *
- * @result Pointer to the face.
- */
-always_inline hicn_face_t *
-hicn_face_ip6_get (const ip6_address_t * addr, u32 sw_if, mhash_t * hashtb)
-{
- hicn_face_ip_key_t key;
-
- hicn_face_ip6_get_key (addr, sw_if, &key);
-
- hicn_face_id_t *dpoi_index = (hicn_face_id_t *) mhash_get (hashtb,
- &key);
-
- return dpoi_index == NULL ? NULL : hicn_dpoi_get_from_idx (*dpoi_index);
-}
-
-/**
- * @brief Create a new face ip. API for other modules (e.g., routing)
- *
- * @param local_addr Local ip v4 or v6 address of the face
- * @param remote_addr Remote ip v4 or v6 address of the face
- * @param sw_if interface associated to the face
- * @param is_app_face Boolean to set the face as an application face
- * @param pfaceid Pointer to return the face id
- * @param is_app_prod if HICN_FACE_FLAGS_APPFACE_PROD the face is a local application face, all other values are ignored
- * @return HICN_ERROR_FACE_NO_GLOBAL_IP if the face does not have a globally
- * reachable ip address, otherwise HICN_ERROR_NONE
- */
-int hicn_face_ip_add (const ip46_address_t * local_addr,
- const ip46_address_t * remote_addr,
- int swif, hicn_face_id_t * pfaceid, u8 is_app_prod);
-
-/**
- * @brief Create a new incomplete face ip. (Meant to be used by the data plane)
- *
- * @param local_addr Local ip v4 or v6 address of the face
- * @param remote_addr Remote ip v4 or v6 address of the face
- * @param sw_if interface associated to the face
- * @param pfaceid Pointer to return the face id
- * @return HICN_ERROR_FACE_NO_GLOBAL_IP if the face does not have a globally
- * reachable ip address, otherwise HICN_ERROR_NONE
- */
-always_inline void
-hicn_iface_ip_add (const ip46_address_t * local_addr,
- const ip46_address_t * remote_addr,
- int sw_if, hicn_face_id_t * pfaceid)
-{
- hicn_face_t *face;
- pool_get (hicn_dpoi_face_pool, face);
-
- hicn_face_ip_t *ip_face = (hicn_face_ip_t *) (face->data);
-
- clib_memcpy (&(ip_face->local_addr.ip6), local_addr,
- sizeof (ip6_address_t));
- clib_memcpy (&(ip_face->remote_addr.ip6), remote_addr,
- sizeof (ip6_address_t));
- face->shared.sw_if = sw_if;
-
- face->shared.adj = ADJ_INDEX_INVALID;
- face->shared.pl_id = (u16) 0;
- face->shared.face_type = hicn_face_ip_type;
- face->shared.flags = HICN_FACE_FLAGS_IFACE;
- face->shared.locks = 1;
-
- hicn_face_ip_key_t key;
- hicn_face_ip6_get_key (&(remote_addr->ip6), sw_if, &key);
- *pfaceid = hicn_dpoi_get_index (face);
-
- mhash_set_mem (&hicn_face_ip_remote_hashtb, &key, (uword *) pfaceid, 0);
-
- for (int i = 0; i < HICN_N_COUNTER; i++)
- {
- vlib_validate_combined_counter (&counters[(*pfaceid) * HICN_N_COUNTER],
- i);
- vlib_zero_combined_counter (&counters[(*pfaceid) * HICN_N_COUNTER], i);
- }
-}
-
-/**
- * @brief Delete an ip face
- *
- * @param face_id Id of the face to delete
- * @return HICN_ERROR_FACE_NOT_FOUND if the face does not exist, otherwise
- * HICN_ERROR_NONE
- */
-int hicn_face_ip_del (hicn_face_id_t face_id);
-
-/**
- * @brief Format a IP face
- *
- * @param s Pointer to a previous string. If null it will be initialize
- * @param args Array storing input values. Expected u32 face_id and u32 indent
- * @return String with the formatted face
- */
-u8 *format_hicn_face_ip (u8 * s, va_list * args);
-
-/**
- * @brief Create a dpo from an ip face
- *
- * @param face Face from which to create the dpo
- * @return the dpo
- */
-void hicn_face_ip_get_dpo (hicn_face_t * face, dpo_id_t * dpo);
-
-#endif // __HICN_FACE_IP_H__
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/hicn-plugin/src/faces/ip/face_ip_cli.c b/hicn-plugin/src/faces/ip/face_ip_cli.c
deleted file mode 100644
index 4c4986f97..000000000
--- a/hicn-plugin/src/faces/ip/face_ip_cli.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (c) 2017-2019 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 <vnet/vnet.h>
-#include <vnet/dpo/dpo.h>
-#include <vlib/vlib.h>
-
-#include "face_ip.h"
-#include "dpo_ip.h"
-#include "../face.h"
-
-#define HICN_FACE_NONE 0
-#define HICN_FACE_DELETE 1
-#define HICN_FACE_ADD 2
-
-static clib_error_t *
-hicn_face_ip_cli_set_command_fn (vlib_main_t * vm,
- unformat_input_t * main_input,
- vlib_cli_command_t * cmd)
-{
- vnet_main_t *vnm = vnet_get_main ();
- ip46_address_t local_addr;
- ip46_address_t remote_addr;
- hicn_face_id_t face_id = HICN_FACE_NULL;
- int ret = HICN_ERROR_NONE;
- int sw_if;
- int face_op = HICN_FACE_NONE;
-
- ip46_address_reset (&local_addr);
- /* Get a line of input. */
- unformat_input_t _line_input, *line_input = &_line_input;
- if (!unformat_user (main_input, unformat_line_input, line_input))
- {
- return (0);
- }
-
- while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (line_input, "del"))
- {
- if (unformat (line_input, "id %d", &face_id))
- face_op = HICN_FACE_DELETE;
- else
- {
- return clib_error_return (0, "missing face id");
- }
- }
- else if (unformat (line_input, "add"))
- {
- face_op = HICN_FACE_ADD;
- if (unformat (line_input, "local %U",
- unformat_ip46_address, &local_addr, IP46_TYPE_ANY));
-
- if (unformat (line_input, "remote %U intfc %U",
- unformat_ip46_address, &remote_addr,
- IP46_TYPE_ANY, unformat_vnet_sw_interface, vnm,
- &sw_if));
- else
- {
- return clib_error_return (0, "%s '%U'",
- get_error_string
- (HICN_ERROR_CLI_INVAL),
- format_unformat_error, line_input);
- }
- }
- else
- {
- return clib_error_return (0, "%s '%U'",
- get_error_string (HICN_ERROR_CLI_INVAL),
- format_unformat_error, line_input);
- }
- }
-
- if (face_id != HICN_FACE_NULL)
- {
-
- if (!hicn_dpoi_idx_is_valid (face_id))
- {
- return clib_error_return (0, "%s, face_id %d not valid",
- get_error_string (ret), face_id);
- }
- }
-
- int rv;
- switch (face_op)
- {
- case HICN_FACE_ADD:
-
- /* Check for presence of next hop address */
- if ((remote_addr.as_u64[0] == (u64) 0)
- && (remote_addr.as_u64[1] == (u64) 0))
- {
- return clib_error_return (0, "next hop address not specified");
- }
-
- if (ip46_address_is_zero (&local_addr))
- {
- if (!vnet_sw_interface_is_valid (vnm, sw_if))
- return clib_error_return (0, "interface not valid");
-
- if (ip46_address_is_ip4 (&remote_addr))
- {
- ip_interface_address_t *interface_address;
- ip4_address_t *addr =
- ip4_interface_address_matching_destination (&ip4_main,
- &remote_addr.ip4,
- sw_if,
- &interface_address);
-
- if (addr == NULL)
- addr = ip4_interface_first_address (&ip4_main,
- sw_if,
- &interface_address);
-
- if (addr == NULL)
- return clib_error_return (0,
- "no valid ip address on interface %d",
- sw_if);
-
- ip46_address_set_ip4 (&local_addr, addr);
- }
- else
- {
- ip_interface_address_t *interface_address;
- ip6_interface_address_matching_destination (&ip6_main,
- &remote_addr.ip6,
- sw_if,
- &interface_address);
-
- ip6_address_t *addr = NULL;
- if (interface_address != NULL)
- addr =
- (ip6_address_t *)
- ip_interface_address_get_address (&ip6_main.lookup_main,
- interface_address);
-
- if (addr == NULL)
- addr = ip6_interface_first_address (&ip6_main, sw_if);
-
- if (addr == NULL)
- return clib_error_return (0,
- "no valid ip address on interface %d",
- sw_if);
-
- ip46_address_set_ip6 (&local_addr, addr);
- }
- }
-
- rv = hicn_face_ip_add (&local_addr, &remote_addr, sw_if, &face_id, 0);
-
- if (rv == HICN_ERROR_NONE)
- {
- vlib_cli_output (vm, "Face id: %d", face_id);
- }
- else
- {
- return clib_error_return (0, get_error_string (rv));
- }
- break;
- case HICN_FACE_DELETE:
- rv = hicn_face_ip_del (face_id);
- if (rv == HICN_ERROR_NONE)
- {
- vlib_cli_output (vm, "Face %d deleted", face_id);
- }
- else
- {
- return clib_error_return (0, get_error_string (rv));
- }
- break;
- default:
- return clib_error_return (0, "Operation (%d) not implemented", face_op);
- break;
- }
- return (rv == HICN_ERROR_NONE) ? 0 : clib_error_return (0, "%s\n",
- get_error_string
- (rv));
-}
-
-/* cli declaration for 'cfg face' */
-/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (hicn_face_ip_cli_set_command, static) =
-{
- .path = "hicn face ip",
- .short_help = "hicn face ip {add [local <src_address>] remote <dst_address> intfc <sw_if>} | {del id <face_id>}",
- .function = hicn_face_ip_cli_set_command_fn,
-};
-/* *INDENT-ON* */
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/hicn-plugin/src/faces/ip/face_ip_node.h b/hicn-plugin/src/faces/ip/face_ip_node.h
deleted file mode 100644
index 000395a04..000000000
--- a/hicn-plugin/src/faces/ip/face_ip_node.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2017-2019 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_IP_NODE_H__
-#define __HICN_FACE_IP_NODE_H__
-
-#include <vlib/vlib.h>
-#include <vnet/vnet.h>
-
-extern vlib_node_registration_t hicn_face_ip4_input_node;
-extern vlib_node_registration_t hicn_face_ip4_output_node;
-extern vlib_node_registration_t hicn_face_ip6_input_node;
-extern vlib_node_registration_t hicn_face_ip6_output_node;
-
-/**
- * @brief Initialize the ip face module
- */
-void hicn_face_ip_init (vlib_main_t * vm);
-
-#endif // __HICN_FACE_IP_NODE_H__
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/hicn-plugin/src/faces/udp/dpo_udp.c b/hicn-plugin/src/faces/udp/dpo_udp.c
deleted file mode 100644
index 987d52bb7..000000000
--- a/hicn-plugin/src/faces/udp/dpo_udp.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (c) 2017-2019 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 "dpo_udp.h"
-
-#include <vnet/ip/format.h>
-#include <vnet/adj/adj.h>
-#include <vnet/vnet.h>
-#include <vlib/vlib.h>
-
-const static char *const hicn_face_ip4udp_nodes[] = {
- "hicn-face-encap-udp4",
- "hicn-face-decap-udp4",
- "hicn-iface-decap-udp4",
- "hicn-iface-encap-udp4",
- NULL,
-};
-
-const static char *const hicn_face_ip6udp_nodes[] = {
- "hicn-face-encap-udp6",
- "hicn-face-decap-udp6",
- "hicn-iface-decap-udp6",
- "hicn-iface-encap-udp6",
- NULL,
-};
-
-const static char *const *const hicn_ipudp_nodes[DPO_PROTO_NUM] = {
- [DPO_PROTO_IP4] = hicn_face_ip4udp_nodes,
- [DPO_PROTO_IP6] = hicn_face_ip6udp_nodes
-};
-
-
-const static dpo_vft_t hicn_dpoi_udp_vft = {
- .dv_lock = hicn_face_lock,
- .dv_unlock = hicn_face_unlock,
- .dv_format = format_hicn_face_udp,
-};
-
-/* Must be executed after all the strategy nodes are created */
-void
-hicn_dpo_udp_module_init (void)
-{
- mhash_init (&hicn_face_udp_hashtb, sizeof (hicn_face_id_t) /* value */ ,
- sizeof (hicn_face_udp_key_t) /* key */ );
-
- /*
- * How much useful is the following registration?
- * So far it seems that we need it only for setting the dpo_type.
- */
- hicn_face_udp_type =
- dpo_register_new_type (&hicn_dpoi_udp_vft, hicn_ipudp_nodes);
-}
-
-
-/* Here udp ports are in host order, move them to network order to do the lookup */
-int
-hicn_dpo_udp4_create (dpo_id_t * dpo,
- const ip4_address_t * src_ip,
- const ip4_address_t * dst_ip,
- u16 src_port, u16 dst_port,
- u32 sw_if,
- adj_index_t ip_adj,
- u32 node_index,
- hicn_face_flags_t flags, hicn_face_id_t * face_id)
-{
- u16 net_src_port = clib_host_to_net_u16 (src_port);
- u16 net_dst_port = clib_host_to_net_u16 (dst_port);
- hicn_face_t *face =
- hicn_face_udp4_get (src_ip, dst_ip, net_src_port, net_dst_port);
-
- u8 hicnb_flags;
- /* ip_csum_t sum0; */
-
- if (face != NULL)
- return HICN_ERROR_FACE_ALREADY_CREATED;
-
- hicn_dpo_udp4_add_and_lock (dpo, src_ip, dst_ip, net_src_port, net_dst_port,
- node_index, &hicnb_flags, sw_if);
-
- face = hicn_dpoi_get_from_idx (dpo->dpoi_index);
-
- hicn_face_udp_t *udp_face = (hicn_face_udp_t *) face->data;
-
- udp_face->hdrs.ip4.ip.checksum =
- ip4_header_checksum (&(udp_face->hdrs.ip4.ip));
-
- face->shared.flags = flags;
- face->shared.adj = ip_adj;
- *face_id = hicn_dpoi_get_index (face);
-
- return HICN_ERROR_NONE;
-}
-
-
-int
-hicn_dpo_udp6_create (dpo_id_t * dpo,
- const ip6_address_t * src_ip,
- const ip6_address_t * dst_ip,
- u16 src_port, u16 dst_port,
- u32 sw_if,
- adj_index_t ip_adj,
- u32 node_index,
- hicn_face_flags_t flags, hicn_face_id_t * face_id)
-{
- u16 net_src_port = clib_host_to_net_u16 (src_port);
- u16 net_dst_port = clib_host_to_net_u16 (dst_port);
- hicn_face_t *face =
- hicn_face_udp6_get (src_ip, dst_ip, net_src_port, net_dst_port);
- u8 hicnb_flags;
-
- if (face != NULL)
- return HICN_ERROR_FACE_ALREADY_CREATED;
-
- hicn_dpo_udp6_add_and_lock (dpo, src_ip, dst_ip, net_src_port, net_dst_port,
- node_index, &hicnb_flags, sw_if);
-
- face = hicn_dpoi_get_from_idx (dpo->dpoi_index);
-
- face->shared.flags = flags;
- face->shared.adj = ip_adj;
- *face_id = hicn_dpoi_get_index (face);
-
- return HICN_ERROR_NONE;
-}
-
-void
-hicn_dpo_udp_create_from_face (hicn_face_t * face, dpo_id_t * dpo,
- u16 dpoi_next_node)
-{
- hicn_face_id_t face_dpoi_id = hicn_dpoi_get_index (face);
- hicn_face_udp_t *face_udp = (hicn_face_udp_t *) face->data;
- u8 version =
- (face_udp->hdrs.ip4.ip.ip_version_and_header_length & 0xf0) >> 4;
- dpo_set (dpo, face->shared.face_type,
- version == 4 ? DPO_PROTO_IP4 : DPO_PROTO_IP6, face_dpoi_id);
- dpo->dpoi_next_node = dpoi_next_node;
-}
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/hicn-plugin/src/faces/udp/dpo_udp.h b/hicn-plugin/src/faces/udp/dpo_udp.h
deleted file mode 100644
index 98abf3d29..000000000
--- a/hicn-plugin/src/faces/udp/dpo_udp.h
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * Copyright (c) 2017-2019 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_DPO_UDP_H__
-#define __HICN_DPO_UDP_H__
-
-#include <vnet/adj/adj_types.h>
-#include <vnet/ip/ip4_packet.h>
-#include <vnet/ip/ip6_packet.h>
-
-#include "face_udp.h"
-#include "../face.h"
-#include "../../error.h"
-
-extern u32 strategy_face_udp4_vlib_edge;
-extern u32 strategy_face_udp6_vlib_edge;
-
-
-/**
- * @brief Initialize the internal structures of the dpo udp face module.
- */
-void hicn_dpo_udp_module_init (void);
-
-/**
- * @brief Create a udp face and its corresponding dpo. Meant to be used for the
- * control plane.
- *
- * @param dpo: Data plane object that point to the face created.
- * @param local_addr: Local address of the UDP tunnel
- * @param remote_addr: Remote address of the UDP tunnel
- * @param local_port: Local port of the UDP tunnel
- * @param remote_port: Remote port of the UDP tunnel
- * @param adj: Ip adjacency corresponding to the remote address in the face
- * @param node_index: vlib edge index to use in the packet processing
- * @param flags: Flags of the face
- * @param face_id: Identifier for the face (dpoi_index)
- * @return HICN_ERROR_FACE_ALREADY_CREATED if the face exists, otherwise HICN_ERROR_NONE
- */
-int
-hicn_dpo_udp4_create (dpo_id_t * dpo,
- const ip4_address_t * local_addr,
- const ip4_address_t * remote_addr,
- u16 local_port, u16 remote_port,
- u32 sw_if,
- adj_index_t adj,
- u32 node_index,
- hicn_face_flags_t flags, hicn_face_id_t * face_id);
-
-/**
- * @brief Retrieve a face using the face identifier, i.e., the quadruplet (local_addr, remote_addr,
- * local_port, remote_port). This method adds a lock on the face state.
- *
- * @param dpo: Result of the lookup. If the face doesn't exist dpo = NULL
- * @param local_addr: Local address of the UDP tunnel
- * @param remote_addr: Remote address of the UDP tunnel
- * @param local_port: Local port of the UDP tunnel
- * @param remote_port: Remote port of the UDP tunnel
- * @param hicnb_flags: Flags that indicate whether the face is an application
- * face or not in the hicn_buffer. (Currently only IP faces can be appface)
- *
- * @result HICN_ERROR_FACE_NOT_FOUND if the face does not exist, otherwise HICN_ERROR_NONE.
- */
-always_inline int
-hicn_dpo_udp4_lock (dpo_id_t * dpo,
- const ip4_address_t * local_addr,
- const ip4_address_t * remote_addr,
- u16 local_port, u16 remote_port, u8 * hicnb_flags)
-{
- dpo->dpoi_type = DPO_FIRST;
- dpo->dpoi_proto = DPO_PROTO_NONE;
- dpo->dpoi_index = INDEX_INVALID;
- dpo->dpoi_next_node = 0;
-
- hicn_face_t *face =
- hicn_face_udp4_get (local_addr, remote_addr, local_port, remote_port);
-
- if (PREDICT_FALSE (face == NULL))
- return HICN_ERROR_FACE_NOT_FOUND;
-
- index_t dpoi_index = hicn_dpoi_get_index (face);
- dpo_set (dpo, hicn_face_udp_type, DPO_PROTO_IP4, dpoi_index);
- dpo->dpoi_next_node = strategy_face_udp4_vlib_edge;
- dpo_unlock (dpo);
-
- *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
-
- return HICN_ERROR_NONE;
-}
-
-/**
- * @brief Retrieve, or create if it doesn't exist, a face from the face
- * identifier (local_addr, remote_addr, local_port, remote_port) and returns its
- * dpo. This method adds a lock on the face state.
- *
- * @param dpo: Result of the lookup
- * @param local_addr: Local address of the UDP tunnel
- * @param remote_addr: Remote address of the UDP tunnel
- * @param local_port: Local port of the UDP tunnel
- * @param remote_port: Remote port of the UDP tunnel
- * @param hicnb_flags: Flags that indicate whether the face is an application
- * face or not. (Currently only IP faces can be appface)
- * @param node_index: vlib edge index to use in the packet processing
- */
-always_inline void
-hicn_dpo_udp4_add_and_lock (dpo_id_t * dpo,
- const ip4_address_t * local_addr,
- const ip4_address_t * remote_addr,
- u16 local_port, u16 remote_port,
- u32 node_index, u8 * hicnb_flags, u32 sw_if)
-{
- dpo->dpoi_type = DPO_FIRST;
- dpo->dpoi_proto = DPO_PROTO_NONE;
- dpo->dpoi_index = INDEX_INVALID;
- dpo->dpoi_next_node = 0;
-
- hicn_face_t *face =
- hicn_face_udp4_get (local_addr, remote_addr, local_port, remote_port);
-
- if (face == NULL)
- {
-
- hicn_face_id_t dpoi_index;
- hicn_iface_udp4_add (local_addr, remote_addr, local_port, remote_port,
- sw_if, &dpoi_index);
-
- *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
- dpo_set (dpo, hicn_face_udp_type, DPO_PROTO_IP4, dpoi_index);
- dpo->dpoi_next_node = node_index;
- dpo_unlock (dpo);
-
- return;
- }
-
- *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
-
- hicn_face_id_t dpoi_index = hicn_dpoi_get_index (face);
- dpo_set (dpo, hicn_face_udp_type, DPO_PROTO_IP4, dpoi_index);
- dpo->dpoi_next_node = node_index;
- dpo_unlock (dpo);
-}
-
-/**
- * @brief Create a udp face and its corresponding dpo. Meant to be used for the
- * control plane.
- *
- * @param dpo: Data plane object that point to the face created.
- * @param local_addr: Local address of the UDP tunnel
- * @param remote_addr: Remote address of the UDP tunnel
- * @param local_port: Local port of the UDP tunnel
- * @param remote_port: Remote port of the UDP tunnel
- * @param adj: Ip adjacency corresponding to the remote address in the face
- * @param node_index: vlib edge index to use in the packet processing
- * @param flags: Flags of the face
- * @param face_id: Identifier for the face (dpoi_index)
- * @return HICN_ERROR_FACE_ALREADY_CREATED if the face exists, otherwise HICN_ERROR_NONE
- */
-int
-hicn_dpo_udp6_create (dpo_id_t * dpo,
- const ip6_address_t * local_addr,
- const ip6_address_t * remote_addr,
- u16 local_port, u16 remote_port,
- u32 sw_if,
- adj_index_t adj,
- u32 node_index,
- hicn_face_flags_t flags, hicn_face_id_t * face_id);
-
-
-/**
- * @brief Retrieve a face using the face identifier, i.e., the quadruplet (local_addr, remote_addr,
- * local_port, remote_port). This method adds a lock on the face state.
- *
- * @param dpo: Result of the lookup. If the face doesn't exist dpo = NULL
- * @param local_addr: Local address of the UDP tunnel
- * @param remote_addr: Remote address of the UDP tunnel
- * @param local_port: Local port of the UDP tunnel
- * @param remote_port: Remote port of the UDP tunnel
- * @param hicnb_flags: Flags that indicate whether the face is an application
- * face or not. (Currently only IP faces can be appface)
- *
- * @result HICN_ERROR_FACE_NOT_FOUND if the face does not exist, otherwise HICN_ERROR_NONE.
- */
-always_inline int
-hicn_dpo_udp6_lock (dpo_id_t * dpo,
- const ip6_address_t * local_addr,
- const ip6_address_t * remote_addr,
- u16 local_port, u16 remote_port, u8 * hicnb_flags)
-{
- dpo->dpoi_type = DPO_FIRST;
- dpo->dpoi_proto = DPO_PROTO_NONE;
- dpo->dpoi_index = INDEX_INVALID;
- dpo->dpoi_next_node = 0;
-
- hicn_face_t *face =
- hicn_face_udp6_get (local_addr, remote_addr, local_port, remote_port);
-
-
- if (PREDICT_FALSE (face == NULL))
- return HICN_ERROR_FACE_NOT_FOUND;
-
- hicn_face_id_t dpoi_index = hicn_dpoi_get_index (face);
- dpo_set (dpo, hicn_face_udp_type, DPO_PROTO_IP6, dpoi_index);
- dpo->dpoi_next_node = strategy_face_udp6_vlib_edge;
- dpo_unlock (dpo);
- *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
-
- return HICN_ERROR_NONE;
-}
-
-/**
- * @brief Retrieve, or create if it doesn't exist, a face from the face
- * identifier (local_addr, remote_addr, local_port, remote_port) and returns its
- * dpo. This method adds a lock on the face state.
- *
- * @param dpo: Result of the lookup
- * @param local_addr: Local address of the UDP tunnel
- * @param remote_addr: Remote address of the UDP tunnel
- * @param local_port: Local port of the UDP tunnel
- * @param remote_port: Remote port of the UDP tunnel
- * @param hicnb_flags: Flags that indicate whether the face is an application
- * face or not. (Currently only IP faces can be appface)
- * @param node_index: vlib edge index to use in the packet processing
- */
-always_inline void
-hicn_dpo_udp6_add_and_lock (dpo_id_t * dpo,
- const ip6_address_t * local_addr,
- const ip6_address_t * remote_addr,
- u16 local_port, u16 remote_port,
- u32 node_index, u8 * hicnb_flags, u32 sw_if)
-{
- dpo->dpoi_type = DPO_FIRST;
- dpo->dpoi_proto = DPO_PROTO_NONE;
- dpo->dpoi_index = INDEX_INVALID;
- dpo->dpoi_next_node = 0;
-
- hicn_face_t *face =
- hicn_face_udp6_get (local_addr, remote_addr, local_port, remote_port);
-
- if (face == NULL)
- {
- hicn_face_id_t dpoi_index;
- hicn_iface_udp6_add (local_addr, remote_addr, local_port, remote_port,
- sw_if, &dpoi_index);
-
- *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
- dpo_set (dpo, hicn_face_udp_type, DPO_PROTO_IP6, dpoi_index);
- dpo->dpoi_next_node = node_index;
- dpo_unlock (dpo);
-
- return;
- }
-
- *hicnb_flags = HICN_BUFFER_FLAGS_DEFAULT;
-
- hicn_face_id_t dpoi_index = hicn_dpoi_get_index (face);
- dpo_set (dpo, hicn_face_udp_type, DPO_PROTO_IP6, dpoi_index);
- dpo->dpoi_next_node = node_index;
- dpo_unlock (dpo);
-}
-
-/**
- * @brief Create a dpo from a udp face
- *
- * @param face Face from which to create the dpo
- * @return the dpo
- */
-void hicn_dpo_udp_create_from_face (hicn_face_t * face, dpo_id_t * dpo,
- u16 dpoi_next_node);
-
-#endif // __HICN_DPO_UDP_H__
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/hicn-plugin/src/faces/udp/face_udp.c b/hicn-plugin/src/faces/udp/face_udp.c
deleted file mode 100644
index e610cbd14..000000000
--- a/hicn-plugin/src/faces/udp/face_udp.c
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * Copyright (c) 2017-2019 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 "face_udp.h"
-#include "face_udp_node.h"
-#include "dpo_udp.h"
-#include "../face.h"
-#include "../../infra.h"
-#include "../../strategy.h"
-#include "../../strategy_dpo_manager.h"
-#include "../../hicn.h"
-
-#include "../../mapme.h" // HICN_MAPME_EVENT_*
-#include "../../mapme_eventmgr.h" // hicn_mapme_eventmgr_process_node
-extern vlib_node_registration_t hicn_mapme_eventmgr_process_node;
-
-mhash_t hicn_face_udp_hashtb;
-
-dpo_type_t hicn_face_udp_type;
-
-ip4_header_t ip4_header_skl = {
- .ip_version_and_header_length = IP4_VERSION_AND_HEADER_LENGTH_NO_OPTIONS,
- .tos = 0x00,
- .length = (u16) 0,
- .fragment_id = (u16) 0,
- .flags_and_fragment_offset = (u16) 0,
- .ttl = 254,
- .protocol = IP_PROTOCOL_UDP,
- .checksum = 0,
- .src_address = {{0}},
- .dst_address = {{0}},
-};
-
-ip6_header_t ip6_header_skl = {
-#if CLIB_ARCH_IS_BIG_ENDIAN
- .ip_version_traffic_class_and_flow_label = 0x60000000,
-#else
- .ip_version_traffic_class_and_flow_label = 0x00000060,
-#endif
- .payload_length = (u16) 0,
- .protocol = IP_PROTOCOL_UDP,
- .hop_limit = 254,
- .src_address = {{0}},
- .dst_address = {{0}}
-};
-
-u32 strategy_face_udp4_vlib_edge;
-u32 strategy_face_udp6_vlib_edge;
-
-/*
- * Separated from the hicn_face_udp_init because it cannot be called by the
- * init macro due to dependencies with other modules not yet initialied
- */
-void
-hicn_face_udp_init_internal ()
-{
- ip4_header_t *ip4_hdr = &ip4_header_skl;
- ip4_header_skl.checksum = ip4_header_checksum (ip4_hdr);
-}
-
-void
-hicn_face_udp_init (vlib_main_t * vm)
-{
- int strategy_nodes_n = hicn_strategy_get_all_available ();
-
- /* Default Strategy has index 0 and it always exists */
- strategy_face_udp4_vlib_edge = vlib_node_add_next (vm,
- hicn_strategy_node.index,
- hicn_face_udp4_output_node.
- index);
- strategy_face_udp6_vlib_edge =
- vlib_node_add_next (vm, hicn_strategy_node.index,
- hicn_face_udp6_output_node.index);
-
- /*
- * Create and edge between al the other strategy nodes and the
- * udp_output nodes.
- */
- for (int i = 1; i < strategy_nodes_n; i++)
- {
- u32 temp_index4 = vlib_node_add_next (vm,
- hicn_strategy_node.index,
- hicn_face_udp4_output_node.index);
- u32 temp_index6 = vlib_node_add_next (vm,
- hicn_strategy_node.index,
- hicn_face_udp6_output_node.index);
- ASSERT (temp_index4 == strategy_face_udp4_vlib_edge);
- ASSERT (temp_index6 == strategy_face_udp6_vlib_edge);
- }
-
- u32 temp_index4 = vlib_node_add_next (vm,
- hicn_interest_hitpit_node.index,
- hicn_face_udp4_output_node.index);
- u32 temp_index6 = vlib_node_add_next (vm,
- hicn_interest_hitpit_node.index,
- hicn_face_udp6_output_node.index);
-
- ASSERT (temp_index4 == strategy_face_udp4_vlib_edge);
- ASSERT (temp_index6 == strategy_face_udp6_vlib_edge);
-
- hicn_dpo_udp_module_init ();
-
- register_face_type (hicn_face_udp_type, &udp_vft, "udp");;
-}
-
-int
-hicn_face_udp_add (const ip46_address_t * local_addr,
- const ip46_address_t * remote_addr, u16 local_port,
- u16 remote_port, u32 swif, hicn_face_id_t * pfaceid)
-{
- adj_index_t ip_adj;
- int ret = HICN_ERROR_NONE;
- dpo_proto_t dpo_proto;
-
- hicn_face_flags_t flags = (hicn_face_flags_t) 0;
- flags |= HICN_FACE_FLAGS_FACE;
-
-
- if (ip46_address_is_ip4 (local_addr) && ip46_address_is_ip4 (remote_addr))
- {
- fib_prefix_t fib_pfx;
- fib_node_index_t fib_entry_index;
- fib_prefix_from_ip46_addr (remote_addr, &fib_pfx);
- fib_pfx.fp_len = ip46_address_is_ip4 (remote_addr) ? 32 : 128;
-
- u32 fib_index = fib_table_find_or_create_and_lock (fib_pfx.fp_proto,
- HICN_FIB_TABLE,
- FIB_SOURCE_PRIORITY_HI);
- fib_entry_index = fib_table_lookup (fib_index, &fib_pfx);
-
- ip_adj = fib_entry_get_adj (fib_entry_index);
-
- if (ip_adj == ~0)
- return HICN_ERROR_FACE_IP_ADJ_NOT_FOUND;
-
- hicn_face_t *face =
- hicn_face_udp4_get (&local_addr->ip4, &remote_addr->ip4, local_port,
- remote_port);
-
- if (face == NULL)
- pool_get (hicn_dpoi_face_pool, face);
-
- hicn_face_udp_t *udp_face = (hicn_face_udp_t *) face->data;
-
- clib_memcpy (&(udp_face->hdrs.ip4.ip), &ip4_header_skl,
- sizeof (ip4_header_t));
- clib_memcpy (&(udp_face->hdrs.ip4.ip.src_address), &(local_addr->ip4),
- sizeof (ip4_address_t));
- clib_memcpy (&(udp_face->hdrs.ip4.ip.dst_address), &(remote_addr->ip4),
- sizeof (ip4_address_t));
-
- udp_face->hdrs.ip4.udp.src_port = local_port;
- udp_face->hdrs.ip4.udp.dst_port = remote_port;
-
- ip_csum_t csum = udp_face->hdrs.ip4.ip.checksum;
- csum = ip_csum_sub_even (csum, ip4_header_skl.src_address.as_u32);
- csum = ip_csum_sub_even (csum, ip4_header_skl.dst_address.as_u32);
- csum =
- ip_csum_add_even (csum, udp_face->hdrs.ip4.ip.src_address.as_u32);
- csum =
- ip_csum_add_even (csum, udp_face->hdrs.ip4.ip.dst_address.as_u32);
- udp_face->hdrs.ip4.ip.checksum = ip_csum_fold (csum);
-
- face->shared.adj = ip_adj;
- face->shared.sw_if = swif;
- face->shared.pl_id = (u16) 0;
- face->shared.face_type = hicn_face_udp_type;
- face->shared.flags = flags;
- face->shared.locks = 0;
-
- hicn_face_udp_key_t key;
- hicn_face_udp4_get_key (&local_addr->ip4, &remote_addr->ip4, local_port,
- remote_port, &key);
- hicn_face_id_t dpoi_index = hicn_dpoi_get_index (face);
-
- mhash_set_mem (&hicn_face_udp_hashtb, &key, (uword *) & dpoi_index, 0);
-
- *pfaceid = hicn_dpoi_get_index (face);
- dpo_proto = DPO_PROTO_IP4;
- fib_table_unlock (fib_index, fib_pfx.fp_proto, FIB_SOURCE_PRIORITY_HI);
- }
- else if (!ip46_address_is_ip4 (local_addr)
- && !ip46_address_is_ip4 (remote_addr))
- {
- fib_prefix_t fib_pfx;
- fib_node_index_t fib_entry_index;
- fib_prefix_from_ip46_addr (remote_addr, &fib_pfx);
- fib_pfx.fp_len = ip46_address_is_ip4 (remote_addr) ? 32 : 128;
-
- u32 fib_index = fib_table_find_or_create_and_lock (fib_pfx.fp_proto,
- HICN_FIB_TABLE,
- FIB_SOURCE_PRIORITY_HI);
- fib_entry_index = fib_table_lookup (fib_index, &fib_pfx);
-
- ip_adj = fib_entry_get_adj (fib_entry_index);
-
- if (ip_adj == ~0)
- return HICN_ERROR_FACE_IP_ADJ_NOT_FOUND;
-
- hicn_face_t *face =
- hicn_face_udp6_get (&local_addr->ip6, &remote_addr->ip6, local_port,
- remote_port);
-
- if (face == NULL)
- pool_get (hicn_dpoi_face_pool, face);
-
- hicn_face_udp_t *udp_face = (hicn_face_udp_t *) face->data;
-
- clib_memcpy (&(udp_face->hdrs.ip6.ip), &ip6_header_skl,
- sizeof (ip6_header_t));
- clib_memcpy (&(udp_face->hdrs.ip6.ip.src_address), local_addr,
- sizeof (ip6_address_t));
- clib_memcpy (&(udp_face->hdrs.ip6.ip.dst_address), remote_addr,
- sizeof (ip6_address_t));
-
- udp_face->hdrs.ip6.udp.src_port = local_port;
- udp_face->hdrs.ip6.udp.dst_port = remote_port;
-
- face->shared.adj = ip_adj;
- face->shared.sw_if = swif;
- face->shared.pl_id = (u16) 0;
- face->shared.face_type = hicn_face_udp_type;
- face->shared.flags = flags;
- face->shared.locks = 0;
-
- hicn_face_udp_key_t key;
- hicn_face_udp6_get_key (&local_addr->ip6, &remote_addr->ip6, local_port,
- remote_port, &key);
- hicn_face_id_t dpoi_index = hicn_dpoi_get_index (face);
-
- mhash_set_mem (&hicn_face_udp_hashtb, &key, (uword *) & dpoi_index, 0);
-
- *pfaceid = hicn_dpoi_get_index (face);
- dpo_proto = DPO_PROTO_IP6;
- fib_table_unlock (fib_index, fib_pfx.fp_proto, FIB_SOURCE_PRIORITY_HI);
- }
- else
- {
- return HICN_ERROR_IPS_ADDR_TYPE_NONUNIFORM;
- }
-
- for (int i = 0; i < HICN_N_COUNTER; i++)
- {
- vlib_validate_combined_counter (&counters[(*pfaceid) * HICN_N_COUNTER],
- i);
- vlib_zero_combined_counter (&counters[(*pfaceid) * HICN_N_COUNTER], i);
- }
-
- retx_t *retx = vlib_process_signal_event_data (vlib_get_main (),
- hicn_mapme_eventmgr_process_node.
- index,
- HICN_MAPME_EVENT_FACE_ADD, 1,
- sizeof (retx_t));
- /* *INDENT-OFF* */
- *retx = (retx_t)
- {
- .prefix = 0,
- .dpo = (dpo_id_t)
- {
- .dpoi_type = hicn_face_udp_type,
- .dpoi_proto = dpo_proto,
- .dpoi_next_node = 0,
- .dpoi_index = *pfaceid,
- }
- };
- /* *INDENT-ON* */
-
- //Take a lock on the face which will be removed when the face is deleted
- hicn_face_lock (&(retx->dpo));
-
- return ret;
-}
-
-int
-hicn_face_udp_del (u32 faceid)
-{
- hicn_face_t *face = hicn_dpoi_get_from_idx (faceid);
- hicn_face_udp_t *face_udp = (hicn_face_udp_t *) face->data;
- hicn_face_udp_key_t key;
- hicn_face_udp_key_t old_key;
-
- if (face_udp->hdrs.ip4.ip.ip_version_and_header_length ==
- IP4_VERSION_AND_HEADER_LENGTH_NO_OPTIONS)
- {
- hicn_face_udp4_get_key (&face_udp->hdrs.ip4.ip.src_address,
- &face_udp->hdrs.ip4.ip.dst_address,
- face_udp->hdrs.ip4.udp.src_port,
- face_udp->hdrs.ip4.udp.dst_port, &key);
- mhash_unset (&hicn_face_udp_hashtb, &key, (uword *) & old_key);
- }
- else
- {
- hicn_face_udp6_get_key (&face_udp->hdrs.ip6.ip.src_address,
- &face_udp->hdrs.ip6.ip.dst_address,
- face_udp->hdrs.ip6.udp.src_port,
- face_udp->hdrs.ip6.udp.dst_port, &key);
- mhash_unset (&hicn_face_udp_hashtb, &key, (uword *) & old_key);
- }
- return hicn_face_del (faceid);
-}
-
-u8 *
-format_hicn_face_udp (u8 * s, va_list * args)
-{
- hicn_face_id_t face_id = va_arg (*args, index_t);
- CLIB_UNUSED (u32 indent) = va_arg (*args, u32);
- hicn_face_t *face;
- hicn_face_udp_t *udp_face;
- ip_adjacency_t *adj;
- u8 ipv = IP4_VERSION_AND_HEADER_LENGTH_NO_OPTIONS;
- vnet_main_t *vnm = vnet_get_main ();
-
-
- face = hicn_dpoi_get_from_idx (face_id);
- udp_face = (hicn_face_udp_t *) (face->data);
-
- if (face->shared.flags & HICN_FACE_FLAGS_FACE)
- {
- ASSERT (face->shared.adj != (adj_index_t) ~ 0);
- adj = adj_get (face->shared.adj);
-
- s = format (s, "%U Face %d: ", format_white_space, indent, face_id);
- if (udp_face->hdrs.ip4.ip.ip_version_and_header_length == ipv)
- {
- s = format (s, "type UDP local %U|%u ",
- format_ip4_address, &udp_face->hdrs.ip4.ip.src_address,
- clib_net_to_host_u16 (udp_face->hdrs.ip4.udp.src_port));
- s =
- format (s, "remote %U|%u ", format_ip4_address,
- &udp_face->hdrs.ip4.ip.dst_address,
- clib_net_to_host_u16 (udp_face->hdrs.ip4.udp.dst_port));
- s = format (s, "%U", format_vnet_link, adj->ia_link);
-
- vnet_sw_interface_t *sw_int =
- vnet_get_sw_interface_or_null (vnm, face->shared.sw_if);
- if (sw_int != NULL)
- s = format (s, " dev %U", format_vnet_sw_interface_name, vnm,
- sw_int);
-
- if ((face->shared.flags & HICN_FACE_FLAGS_DELETED))
- s = format (s, " (deleted)");
- }
- else
- {
- s = format (s, "type UDP local %U|%u ",
- format_ip6_address, &udp_face->hdrs.ip6.ip.src_address,
- clib_net_to_host_u16 (udp_face->hdrs.ip6.udp.src_port));
- s =
- format (s, "remote %U|%u ", format_ip6_address,
- &udp_face->hdrs.ip6.ip.dst_address,
- clib_net_to_host_u16 (udp_face->hdrs.ip6.udp.dst_port));
- s = format (s, "%U", format_vnet_link, adj->ia_link);
-
- vnet_sw_interface_t *sw_int =
- vnet_get_sw_interface_or_null (vnm, face->shared.sw_if);
- if (sw_int != NULL)
- s = format (s, " dev %U", format_vnet_sw_interface_name, vnm,
- sw_int);
-
- if ((face->shared.flags & HICN_FACE_FLAGS_DELETED))
- s = format (s, " (deleted)");
- }
- }
- else
- {
- s = format (s, "%U iFace %d: ", format_white_space, indent, face_id);
- if (udp_face->hdrs.ip4.ip.ip_version_and_header_length == ipv)
- {
- s = format (s, "type UDP local %U|%u",
- format_ip4_address, &udp_face->hdrs.ip4.ip.src_address,
- clib_net_to_host_u16 (udp_face->hdrs.ip4.udp.src_port));
- s =
- format (s, " local %U|%u", format_ip4_address,
- &udp_face->hdrs.ip4.ip.dst_address,
- clib_net_to_host_u16 (udp_face->hdrs.ip4.udp.dst_port));
-
- vnet_sw_interface_t *sw_int =
- vnet_get_sw_interface_or_null (vnm, face->shared.sw_if);
- if (sw_int != NULL)
- s = format (s, " dev %U", format_vnet_sw_interface_name, vnm,
- sw_int);
-
- if ((face->shared.flags & HICN_FACE_FLAGS_DELETED))
- s = format (s, " (deleted)");
- }
- else
- {
- s = format (s, "type UDP local %U|%u",
- format_ip6_address, &udp_face->hdrs.ip6.ip.src_address,
- clib_net_to_host_u16 (udp_face->hdrs.ip6.udp.src_port));
- s =
- format (s, " remote %U|%u", format_ip6_address,
- &udp_face->hdrs.ip6.ip.dst_address,
- clib_net_to_host_u16 (udp_face->hdrs.ip6.udp.dst_port));
-
- vnet_sw_interface_t *sw_int =
- vnet_get_sw_interface_or_null (vnm, face->shared.sw_if);
- if (sw_int != NULL)
- s = format (s, " dev %U", format_vnet_sw_interface_name, vnm,
- sw_int);
-
- if ((face->shared.flags & HICN_FACE_FLAGS_DELETED))
- s = format (s, " (deleted)");
- }
- }
-
- return s;
-}
-
-void
-hicn_face_udp_get_dpo (hicn_face_t * face, dpo_id_t * dpo)
-{
- hicn_face_udp_t *face_udp = (hicn_face_udp_t *) face->data;
- u8 version =
- (face_udp->hdrs.ip4.ip.ip_version_and_header_length & 0xf0) >> 4;
- return hicn_dpo_udp_create_from_face (face, dpo,
- version ==
- (u8) 4 ? strategy_face_udp4_vlib_edge
- : strategy_face_udp6_vlib_edge);
-}
-
-hicn_face_vft_t udp_vft = {
- .format_face = format_hicn_face_udp,
- .hicn_face_del = hicn_face_udp_del,
- .hicn_face_get_dpo = hicn_face_udp_get_dpo,
-};
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/hicn-plugin/src/faces/udp/face_udp.h b/hicn-plugin/src/faces/udp/face_udp.h
deleted file mode 100644
index 5dfc76e22..000000000
--- a/hicn-plugin/src/faces/udp/face_udp.h
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * Copyright (c) 2017-2019 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_UDP_H__
-#define __HICN_FACE_UDP_H__
-
-#include <vlib/vlib.h>
-#include <vnet/vnet.h>
-#include <vnet/ip/ip6_packet.h>
-#include <vnet/udp/udp_packet.h>
-
-#include "../face.h"
-
-/**
- * @file
- * @brief UDP face
- *
- * This file containes the definition of UDP faces.
- * UDP faces encap and decap an hicn packet into a UDP tunnel.
- * Src and dst address in interest and data packets are not considered and
- * should be set to 0 (not checked in the forwarder).
- */
-
-/* Pre-instantiated ip header to fast fill an newly encapsulated packet */
-extern ip4_header_t ip4_header_skl;
-extern ip6_header_t ip6_header_skl;
-
-#define INVALID_UDP_DPO_INDEX ~0
-
-/**
- * @brief UDP face representation. The following is stored in the data field of
- * an hicn_face_t object (see hicn_face.h). A UDP face is identifies by the
- * quadruplet (src addr, dst addr, src port, dst port).
- */
-typedef struct hicn_face_udp_t_
-{
- /**
- * The headers to paint, in packet painting order
- */
- union
- {
- struct
- {
- ip4_header_t ip;
- udp_header_t udp;
- } __attribute__ ((packed)) ip4;
- struct
- {
- ip6_header_t ip;
- udp_header_t udp;
- } __attribute__ ((packed)) ip6;
- } __attribute__ ((packed)) hdrs;
-} hicn_face_udp_t;
-
-/* Hast table mapping the udp key with the face id (dpoi_index pointing to and
- element in the face pool defined in hicn_face.h)*/
-extern mhash_t hicn_face_udp_hashtb;
-
-/**
- * @brief Hash table key.
- */
-typedef struct hicn_face_udp_key_s
-{
- ip46_address_t local_addr;
- ip46_address_t remote_addr;
- u16 local_port;
- u16 remote_port;
-} hicn_face_udp_key_t;
-
-/* DPO type for the udp face */
-extern dpo_type_t hicn_face_udp_type;
-
-/* VFT table for the udp face. Mainly used to format the face in the right way */
-extern hicn_face_vft_t udp_vft;
-
-/**
- * @brief Create the key object for the mhash. Fill in the key object with the
- * expected values.
- *
- * @param local_addr Local address of the UDP tunnel
- * @param remote_addr Remote address of the UDP tunnel
- * @param local_port Local port of the UDP tunnel
- * @param remote_port Remote port of the UDP tunnel
- * @param key Pointer to an allocated hicn_face_udp_key_t object
- */
-always_inline void
-hicn_face_udp4_get_key (const ip4_address_t * local_addr,
- const ip4_address_t * remote_addr,
- u16 local_port, u16 remote_port,
- hicn_face_udp_key_t * key)
-{
-
- ip46_address_set_ip4 (&(key->local_addr), local_addr);
- ip46_address_set_ip4 (&(key->remote_addr), remote_addr);
- key->local_port = local_port;
- key->remote_port = remote_port;
-}
-
-/**
- * @brief Create the key object for the mhash. Fill in the key object with the
- * expected values.
- *
- * @param local_addr Local address of the UDP tunnel
- * @param remote_addr Remote address of the UDP tunnel
- * @param local_port Local port of the UDP tunnel
- * @param remote_port Remote port of the UDP tunnel
- * @param key Pointer to an allocated hicn_face_udp_key_t object
- */
-always_inline void
-hicn_face_udp6_get_key (const ip6_address_t * local_addr,
- const ip6_address_t * remote_addr,
- u16 local_port, u16 remote_port,
- hicn_face_udp_key_t * key)
-{
- key->local_addr.ip6 = *local_addr;
- key->remote_addr.ip6 = *remote_addr;
- key->local_port = local_port;
- key->remote_port = remote_port;
-}
-
-/**
- * @brief Get the dpoi from the quadruplet that identifies the face. Does not add any lock.
- *
- * @param local_addr Local address of the UDP tunnel
- * @param remote_addr Remote address of the UDP tunnel
- * @param local_port Local port of the UDP tunnel
- * @param remote_port Remote port of the UDP tunnel
- *
- * @result Pointer to the face.
- */
-always_inline hicn_face_t *
-hicn_face_udp4_get (const ip4_address_t * local_addr,
- const ip4_address_t * remote_addr,
- u16 local_port, u16 remote_port)
-{
- hicn_face_udp_key_t key;
-
- hicn_face_udp4_get_key (local_addr, remote_addr, local_port, remote_port,
- &key);
-
- hicn_face_id_t *dpoi_index =
- (hicn_face_id_t *) mhash_get (&hicn_face_udp_hashtb,
- &key);
-
- return dpoi_index == NULL ? NULL : hicn_dpoi_get_from_idx (*dpoi_index);
-}
-
-/**
- * @brief Get the dpoi from the quadruplet that identifies the face. Does not add any lock.
- *
- * @param local_addr Local address of the UDP tunnel (network order)
- * @param remote_addr Remote address of the UDP tunnel (network order)
- * @param local_port Local port of the UDP tunnel (network order)
- * @param remote_port Remote port of the UDP tunnel (network order)
- *
- * @result Pointer to the face.
- */
-always_inline hicn_face_t *
-hicn_face_udp6_get (const ip6_address_t * local_addr,
- const ip6_address_t * remote_addr,
- u16 local_port, u16 remote_port)
-{
- hicn_face_udp_key_t key;
-
- hicn_face_udp6_get_key (local_addr, remote_addr, local_port, remote_port,
- &key);
-
- hicn_face_id_t *dpoi_index =
- (hicn_face_id_t *) mhash_get (&hicn_face_udp_hashtb,
- &key);
-
- return dpoi_index == NULL ? NULL : hicn_dpoi_get_from_idx (*dpoi_index);
-}
-
-
-/**
- * @brief Initialize the udp face module
- */
-void hicn_face_udp_init (vlib_main_t * vm);
-
-/**
- * @brief Create a new face ip. API for other modules (e.g., routing)
- *
- * @param local_addr Local ip v4 or v6 address of the face (network order)
- * @param remote_addr Remote ip v4 or v6 address of the face (network order)
- * @param local_port Local udp port of the face (network order)
- * @param remote_port Remote udp port of the face (network order)
- * @param sw_if interface associated to the face
- * @param pfaceid Pointer to return the face id
- * @return HICN_ERROR_FACE_NO_GLOBAL_IP if the face does not have a globally
- * reachable ip address, otherwise HICN_ERROR_NONE
- */
-int hicn_face_udp_add (const ip46_address_t * local_addr,
- const ip46_address_t * remote_addr, u16 local_port,
- u16 remote_port, u32 swif, hicn_face_id_t * pfaceid);
-
-/**
- * @brief Create a new incomplete face udp. (Meant to be used by the data plane)
- *
- * @param local_addr Local ip v6 address of the face
- * @param remote_addr Remote ip v6 address of the face
- * @param sw_if interface associated to the face
- * @param pfaceid Pointer to return the face id
- * @return HICN_ERROR_FACE_NO_GLOBAL_IP if the face does not have a globally
- * reachable ip address, otherwise HICN_ERROR_NONE
- */
-always_inline void
-hicn_iface_udp6_add (const ip6_address_t * local_addr,
- const ip6_address_t * remote_addr, u16 local_port,
- u16 remote_port, int sw_if, hicn_face_id_t * pfaceid)
-{
- hicn_face_t *face;
- pool_get (hicn_dpoi_face_pool, face);
-
- hicn_face_udp_t *udp_face = (hicn_face_udp_t *) face->data;
-
- clib_memcpy (&(udp_face->hdrs.ip6.ip), &ip6_header_skl,
- sizeof (ip6_header_t));
- clib_memcpy (&(udp_face->hdrs.ip6.ip.src_address), local_addr,
- sizeof (ip6_address_t));
- clib_memcpy (&(udp_face->hdrs.ip6.ip.dst_address), remote_addr,
- sizeof (ip6_address_t));
-
- udp_face->hdrs.ip6.udp.src_port = local_port;
- udp_face->hdrs.ip6.udp.dst_port = remote_port;
-
- face->shared.adj = ADJ_INDEX_INVALID;
- face->shared.pl_id = (u16) 0;
- face->shared.face_type = hicn_face_udp_type;
- face->shared.flags = HICN_FACE_FLAGS_IFACE;
- face->shared.locks = 0;
- face->shared.sw_if = sw_if;
-
- hicn_face_udp_key_t key;
- hicn_face_udp6_get_key (local_addr, remote_addr, local_port,
- remote_port, &key);
- *pfaceid = hicn_dpoi_get_index (face);
-
- hicn_face_id_t dpoi_index = hicn_dpoi_get_index (face);
-
- mhash_set_mem (&hicn_face_udp_hashtb, &key, (uword *) & dpoi_index, 0);
-
- for (int i = 0; i < HICN_N_COUNTER; i++)
- {
- vlib_validate_combined_counter (&counters[(*pfaceid) * HICN_N_COUNTER],
- i);
- vlib_zero_combined_counter (&counters[(*pfaceid) * HICN_N_COUNTER], i);
- }
-}
-
-/**
- * @brief Create a new incomplete face udp. (Meant to be used by the data plane)
- *
- * @param local_addr Local ip v4 address of the face
- * @param remote_addr Remote ip v4 address of the face
- * @param sw_if interface associated to the face
- * @param pfaceid Pointer to return the face id
- * @return HICN_ERROR_FACE_NO_GLOBAL_IP if the face does not have a globally
- * reachable ip address, otherwise HICN_ERROR_NONE
- */
-always_inline void
-hicn_iface_udp4_add (const ip4_address_t * local_addr,
- const ip4_address_t * remote_addr, u16 local_port,
- u16 remote_port, int sw_if, hicn_face_id_t * pfaceid)
-{
- hicn_face_t *face;
- pool_get (hicn_dpoi_face_pool, face);
-
- hicn_face_udp_t *udp_face = (hicn_face_udp_t *) face->data;
-
- clib_memcpy (&(udp_face->hdrs.ip4.ip), &ip4_header_skl,
- sizeof (ip4_header_t));
- clib_memcpy (&(udp_face->hdrs.ip4.ip.src_address), local_addr,
- sizeof (ip4_address_t));
- clib_memcpy (&(udp_face->hdrs.ip4.ip.dst_address), remote_addr,
- sizeof (ip4_address_t));
-
- udp_face->hdrs.ip4.udp.src_port = local_port;
- udp_face->hdrs.ip4.udp.dst_port = remote_port;
-
- face->shared.adj = ADJ_INDEX_INVALID;
- face->shared.pl_id = (u16) 0;
- face->shared.face_type = hicn_face_udp_type;
- face->shared.flags = HICN_FACE_FLAGS_IFACE;
- face->shared.locks = 1;
- face->shared.sw_if = sw_if;
-
- hicn_face_udp_key_t key;
- hicn_face_udp4_get_key (local_addr, remote_addr, local_port,
- remote_port, &key);
- *pfaceid = hicn_dpoi_get_index (face);
-
- hicn_face_id_t dpoi_index = hicn_dpoi_get_index (face);
-
- mhash_set_mem (&hicn_face_udp_hashtb, &key, (uword *) & dpoi_index, 0);
-
- for (int i = 0; i < HICN_N_COUNTER; i++)
- {
- vlib_validate_combined_counter (&counters[(*pfaceid) * HICN_N_COUNTER],
- i);
- vlib_zero_combined_counter (&counters[(*pfaceid) * HICN_N_COUNTER], i);
- }
-}
-
-/**
- * @brief Delete an ip face
- *
- * @param face_id Id of the face to delete
- * @return HICN_ERROR_FACE_NOT_FOUND if the face does not exist, otherwise
- * HICN_ERROR_NONE
- */
-int hicn_face_udp_del (hicn_face_id_t faceid);
-
-/**
- * @brief Format a UDP face
- *
- * @param s Pointer to a previous string. If null it will be initialize
- * @param args Array storing input values. Expected u32 indent and u32 face_id
- * @return String with the formatted face
- */
-u8 *format_hicn_face_udp (u8 * s, va_list * args);
-
-/**
- * @brief Create a dpo from a udp face
- *
- * @param face Face from which to create the dpo
- * @return the dpo
- */
-void hicn_face_udp_get_dpo (hicn_face_t * face, dpo_id_t * dpo);
-
-/**
- * @brief Init some internal structures
- */
-void hicn_face_udp_init_internal (void);
-
-#endif // __HICN_FACE_UDP_H__
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/hicn-plugin/src/faces/udp/face_udp_cli.c b/hicn-plugin/src/faces/udp/face_udp_cli.c
deleted file mode 100644
index 7bb172ce8..000000000
--- a/hicn-plugin/src/faces/udp/face_udp_cli.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (c) 2017-2019 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 "face_udp.h"
-#include "dpo_udp.h"
-
-#include <vnet/vnet.h>
-#include <vnet/dpo/dpo.h>
-#include <vlib/vlib.h>
-#include <vnet/ip/format.h>
-
-#define HICN_FACE_NONE 0
-#define HICN_FACE_DELETE 1
-#define HICN_FACE_ADD 2
-
-
-static clib_error_t *
-hicn_face_udp_cli_set_command_fn (vlib_main_t * vm,
- unformat_input_t * main_input,
- vlib_cli_command_t * cmd)
-{
- vnet_main_t *vnm = vnet_get_main ();
- ip46_address_t src_addr;
- u32 src_port = 0;
- ip46_address_t dst_addr;
- u32 dst_port = 0;
- hicn_face_id_t face_id = HICN_FACE_NULL;
- int ret = HICN_ERROR_NONE;
- int sw_if;
- int face_op = HICN_FACE_NONE;
-
- ip46_address_reset (&src_addr);
- ip46_address_reset (&dst_addr);
- /* Get a line of input. */
- unformat_input_t _line_input, *line_input = &_line_input;
- if (!unformat_user (main_input, unformat_line_input, line_input))
- {
- return (0);
- }
-
- while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (line_input, "del"))
- {
- if (unformat (line_input, "id %d", &face_id))
- face_op = HICN_FACE_DELETE;
- else
- {
- return clib_error_return (0, "missing face id");
- }
- }
- else if (unformat (line_input, "add"))
- {
- face_op = HICN_FACE_ADD;
- if (unformat
- (line_input, "src_addr %U port %u dst_addr %U port %u intfc %U",
- unformat_ip46_address, &src_addr, IP46_TYPE_ANY, &src_port,
- unformat_ip46_address, &dst_addr, IP46_TYPE_ANY, &dst_port,
- unformat_vnet_sw_interface, vnm, &sw_if));
- else
- {
- return clib_error_return (0, "%s '%U'",
- get_error_string
- (HICN_ERROR_CLI_INVAL),
- format_unformat_error, line_input);
- }
- }
- else
- {
- return clib_error_return (0, "%s '%U'",
- get_error_string (HICN_ERROR_CLI_INVAL),
- format_unformat_error, line_input);
- }
- }
-
- if (face_id != HICN_FACE_NULL)
- {
- if (!hicn_dpoi_idx_is_valid (face_id))
- {
- return clib_error_return (0, "%s, face_id %d not valid",
- get_error_string (ret), face_id);
- }
- }
-
- int rv;
- switch (face_op)
- {
- case HICN_FACE_ADD:
-
- /* Check for presence of next hop address */
- if (((dst_addr.as_u64[0] == (u64) 0) && (dst_addr.as_u64[1] == (u64) 0))
- || dst_port == 0)
- {
- return clib_error_return (0, "dst address and port not specified");
- }
-
- if (((src_addr.as_u64[0] == (u64) 0) && (src_addr.as_u64[1] == (u64) 0))
- || src_port == 0)
- {
- return clib_error_return (0, "src address not specified");
- }
-
- rv =
- hicn_face_udp_add (&src_addr, &dst_addr,
- clib_host_to_net_u16 (src_port),
- clib_host_to_net_u16 (dst_port), sw_if, &face_id);
- if (rv == HICN_ERROR_NONE)
- {
- vlib_cli_output (vm, "Face id: %d", face_id);
- }
- else
- {
- return clib_error_return (0, get_error_string (rv));
- }
- break;
- case HICN_FACE_DELETE:
- rv = hicn_face_udp_del (face_id);
- if (rv == HICN_ERROR_NONE)
- {
- vlib_cli_output (vm, "Face %d deleted", face_id);
- }
- else
- {
- return clib_error_return (0, get_error_string (rv));
- }
- break;
- default:
- return clib_error_return (0, "Operation (%d) not implemented", face_op);
- break;
- }
- return (rv == HICN_ERROR_NONE) ? 0 : clib_error_return (0, "%s\n",
- get_error_string
- (rv));
-}
-
-/* cli declaration for 'cfg face' */
-/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (hicn_face_udp_cli_set_command, static) =
-{
- .path = "hicn face udp",
- .short_help = "hicn face udp {add src_addr <src_address> port <src_port > dst_addr <dst_address> port <dst_port>} intfc <interface> | {del id <face_id>}",
- .function = hicn_face_udp_cli_set_command_fn,
-};
-/* *INDENT-ON* */
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/hicn-plugin/src/faces/udp/face_udp_node.c b/hicn-plugin/src/faces/udp/face_udp_node.c
deleted file mode 100644
index c82336659..000000000
--- a/hicn-plugin/src/faces/udp/face_udp_node.c
+++ /dev/null
@@ -1,1030 +0,0 @@
-/*
- * Copyright (c) 2017-2019 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/ip/ip_packet.h>
-
-#include "face_udp.h"
-#include "face_udp_node.h"
-#include "dpo_udp.h"
-#include "../face.h"
-#include "../../strategy.h"
-#include "../../strategy_dpo_manager.h"
-#include "../../hicn.h"
-
-/**
- * @File
- *
- * Definition of the nodes for udp faces.
- */
-
-vlib_node_registration_t hicn_face_udp4_input_node;
-vlib_node_registration_t hicn_face_udp6_input_node;
-vlib_node_registration_t hicn_face_udp4_output_node;
-vlib_node_registration_t hicn_face_udp6_output_node;
-
-static char *hicn_face_udp4_input_error_strings[] = {
-#define _(sym, string) string,
- foreach_hicnfwd_error
-#undef _
-};
-
-static char *hicn_face_udp6_input_error_strings[] = {
-#define _(sym, string) string,
- foreach_hicnfwd_error
-#undef _
-};
-
-/* Trace context struct */
-typedef struct
-{
- u32 next_index;
- u32 sw_if_index;
- u8 pkt_type;
- u8 packet_data[60];
-}
-hicn_face_udp4_input_trace_t;
-
-typedef enum
-{
- HICN_FACE_UDP4_INPUT_NEXT_DATA,
- HICN_FACE_UDP4_INPUT_NEXT_MAPME,
- HICN_FACE_UDP4_INPUT_NEXT_ERROR_DROP,
- HICN_FACE_UDP4_INPUT_N_NEXT,
-} hicn_face_udp4_input_next_t;
-
-/* Trace context struct */
-typedef struct
-{
- u32 next_index;
- u32 sw_if_index;
- u8 pkt_type;
- u8 packet_data[60];
-}
-hicn_face_udp6_input_trace_t;
-
-typedef enum
-{
- HICN_FACE_UDP6_INPUT_NEXT_DATA,
- HICN_FACE_UDP6_INPUT_NEXT_MAPME,
- HICN_FACE_UDP6_INPUT_NEXT_ERROR_DROP,
- HICN_FACE_UDP6_INPUT_N_NEXT,
-} hicn_face_udp6_input_next_t;
-
-#define ERROR_INPUT_UDP4 HICN_FACE_UDP4_INPUT_NEXT_ERROR_DROP
-#define ERROR_INPUT_UDP6 HICN_FACE_UDP6_INPUT_NEXT_ERROR_DROP
-
-#define NEXT_MAPME_UDP4 HICN_FACE_UDP4_INPUT_NEXT_MAPME
-#define NEXT_MAPME_UDP6 HICN_FACE_UDP6_INPUT_NEXT_MAPME
-#define NEXT_DATA_UDP4 HICN_FACE_UDP4_INPUT_NEXT_DATA
-#define NEXT_DATA_UDP6 HICN_FACE_UDP6_INPUT_NEXT_DATA
-
-#define IP_HEADER_4 ip4_header_t
-#define IP_HEADER_6 ip6_header_t
-
-#define HICN_DPO_UDP_LOCK_IP4 hicn_dpo_udp4_lock
-#define HICN_DPO_UDP_LOCK_IP6 hicn_dpo_udp6_lock
-
-#define TRACE_INPUT_PKT_UDP4 hicn_face_udp4_input_trace_t
-#define TRACE_INPUT_PKT_UDP6 hicn_face_udp6_input_trace_t
-
-#define SIZE_HICN_HEADER4 sizeof(ip4_header_t) + sizeof(udp_header_t)
-#define SIZE_HICN_HEADER6 sizeof(ip6_header_t) + sizeof(udp_header_t)
-
-
-#define face_input_x1(ipv) \
- do { \
- int ret; \
- vlib_buffer_t *b0; \
- u32 bi0; \
- u32 next0 = ERROR_INPUT_UDP##ipv; \
- IP_HEADER_##ipv * ip_hdr = NULL; \
- u8 * inner_ip_hdr = NULL; \
- udp_header_t * udp_hdr = NULL; \
- hicn_buffer_t * hicnb0; \
- /* 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, STORE); \
- CLIB_PREFETCH (b1->data, CLIB_CACHE_LINE_BYTES , LOAD); \
- } \
- /* Dequeue a packet buffer */ \
- bi0 = from[0]; \
- from += 1; \
- n_left_from -= 1; \
- to_next[0] = bi0; \
- to_next += 1; \
- n_left_to_next -= 1; \
- \
- b0 = vlib_get_buffer (vm, bi0); \
- ip_hdr = (IP_HEADER_##ipv *) vlib_buffer_get_current(b0); \
- udp_hdr = (udp_header_t *) (ip_hdr + 1); \
- hicnb0 = hicn_get_buffer(b0); \
- \
- inner_ip_hdr = (u8 *)(udp_hdr + 1); \
- u8 is_v6 = hicn_is_v6((hicn_header_t *)inner_ip_hdr); \
- u8 is_icmp = is_v6*(inner_ip_hdr[6] == IPPROTO_ICMPV6) + \
- (1 - is_v6)*(inner_ip_hdr[9] == IPPROTO_ICMPV4); \
- \
- ret = HICN_DPO_UDP_LOCK_IP##ipv \
- (&(hicnb0->face_dpo_id), \
- &(ip_hdr->dst_address), \
- &(ip_hdr->src_address), \
- (udp_hdr->dst_port), \
- (udp_hdr->src_port), \
- &hicnb0->flags); \
- \
- if ( PREDICT_FALSE(ret != HICN_ERROR_NONE) ) \
- { \
- next0 = ERROR_INPUT_UDP##ipv; \
- } \
- else \
- { \
- next0 = is_icmp*NEXT_MAPME_UDP##ipv + \
- (1-is_icmp)*NEXT_DATA_UDP##ipv; \
- stats.pkts_data_count += 1; \
- \
- vlib_buffer_advance(b0, sizeof(IP_HEADER_##ipv) + \
- sizeof(udp_header_t)); \
- vlib_increment_combined_counter ( \
- &counters[hicnb0->face_dpo_id.dpoi_index \
- * HICN_N_COUNTER], thread_index, \
- HICN_FACE_COUNTERS_DATA_RX, \
- 1, \
- vlib_buffer_length_in_chain(vm, b0)); \
- } \
- \
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && \
- (b0->flags & VLIB_BUFFER_IS_TRACED))) \
- { \
- TRACE_INPUT_PKT_UDP##ipv *t = \
- vlib_add_trace (vm, node, b0, sizeof (*t)); \
- t->pkt_type = HICN_PKT_TYPE_CONTENT; \
- 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), \
- sizeof (t->packet_data)); \
- } \
- \
- \
- /* 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); \
- }while(0) \
-
-#define face_input_x2(ipv) \
- do { \
- int ret0, ret1; \
- vlib_buffer_t *b0, *b1; \
- u32 bi0, bi1; \
- u32 next0 = ERROR_INPUT_UDP##ipv; \
- u32 next1 = ERROR_INPUT_UDP##ipv; \
- IP_HEADER_##ipv * ip_hdr0 = NULL; \
- IP_HEADER_##ipv * ip_hdr1 = NULL; \
- u8 * inner_ip_hdr0 = NULL; \
- u8 * inner_ip_hdr1 = NULL; \
- udp_header_t * udp_hdr0 = NULL; \
- udp_header_t * udp_hdr1 = NULL; \
- hicn_buffer_t *hicnb0, *hicnb1; \
- \
- /* Prefetch for next iteration. */ \
- { \
- vlib_buffer_t *b2, *b3; \
- b2 = vlib_get_buffer (vm, from[2]); \
- b3 = vlib_get_buffer (vm, from[3]); \
- CLIB_PREFETCH (b2, CLIB_CACHE_LINE_BYTES, STORE); \
- CLIB_PREFETCH (b3, CLIB_CACHE_LINE_BYTES, STORE); \
- CLIB_PREFETCH (b2->data, CLIB_CACHE_LINE_BYTES , LOAD); \
- CLIB_PREFETCH (b3->data, CLIB_CACHE_LINE_BYTES , LOAD); \
- } \
- \
- /* Dequeue a packet buffer */ \
- bi0 = from[0]; \
- bi1 = from[1]; \
- from += 2; \
- n_left_from -= 2; \
- to_next[0] = bi0; \
- to_next[1] = bi1; \
- to_next += 2; \
- n_left_to_next -= 2; \
- \
- b0 = vlib_get_buffer (vm, bi0); \
- b1 = vlib_get_buffer (vm, bi1); \
- ip_hdr0 = (IP_HEADER_##ipv *) vlib_buffer_get_current(b0); \
- ip_hdr1 = (IP_HEADER_##ipv *) vlib_buffer_get_current(b1); \
- udp_hdr0 = (udp_header_t *) (ip_hdr0 + 1); \
- udp_hdr1 = (udp_header_t *) (ip_hdr1 + 1); \
- hicnb0 = hicn_get_buffer(b0); \
- hicnb1 = hicn_get_buffer(b1); \
- \
- inner_ip_hdr0 = (u8 *)(udp_hdr0 + 1); \
- u8 is_v6_0 = hicn_is_v6((hicn_header_t *)inner_ip_hdr0); \
- u8 is_icmp0 = is_v6_0*(inner_ip_hdr0[6] == IPPROTO_ICMPV6) + \
- (1 - is_v6_0)*(inner_ip_hdr0[9] == IPPROTO_ICMPV4); \
- \
- inner_ip_hdr1 = (u8 *)(udp_hdr1 + 1); \
- u8 is_v6_1 = hicn_is_v6((hicn_header_t *)inner_ip_hdr1); \
- u8 is_icmp1 = is_v6_1*(inner_ip_hdr1[6] == IPPROTO_ICMPV6) + \
- (1 - is_v6_1)*(inner_ip_hdr1[9] == IPPROTO_ICMPV4); \
- \
- ret0 = HICN_DPO_UDP_LOCK_IP##ipv \
- (&(hicnb0->face_dpo_id), \
- &(ip_hdr0->dst_address), \
- &(ip_hdr0->src_address), \
- (udp_hdr0->dst_port), \
- (udp_hdr0->src_port), \
- &hicnb0->flags); \
- \
- ret1 = HICN_DPO_UDP_LOCK_IP##ipv \
- (&(hicnb1->face_dpo_id), \
- &(ip_hdr1->dst_address), \
- &(ip_hdr1->src_address), \
- (udp_hdr1->dst_port), \
- (udp_hdr1->src_port), \
- &hicnb1->flags); \
- \
- if ( PREDICT_FALSE(ret0 != HICN_ERROR_NONE) ) \
- { \
- next0 = ERROR_INPUT_UDP##ipv; \
- } \
- else \
- { \
- stats.pkts_data_count += 1; \
- next0 = is_icmp0*NEXT_MAPME_UDP##ipv + \
- (1-is_icmp0)*NEXT_DATA_UDP##ipv; \
- \
- vlib_buffer_advance(b0, sizeof(IP_HEADER_##ipv) + \
- sizeof(udp_header_t)); \
- vlib_increment_combined_counter ( \
- &counters[hicnb0->face_dpo_id.dpoi_index \
- * HICN_N_COUNTER], thread_index, \
- HICN_FACE_COUNTERS_DATA_RX, \
- 1, \
- vlib_buffer_length_in_chain(vm, b0)); \
- } \
- \
- if ( PREDICT_FALSE(ret1 != HICN_ERROR_NONE) ) \
- { \
- next1 = ERROR_INPUT_UDP##ipv; \
- } \
- else \
- { \
- stats.pkts_data_count += 1; \
- next1 = is_icmp1*NEXT_MAPME_UDP##ipv + \
- (1-is_icmp1)*NEXT_DATA_UDP##ipv; \
- \
- vlib_buffer_advance(b1, sizeof(IP_HEADER_##ipv) + \
- sizeof(udp_header_t)); \
- vlib_increment_combined_counter ( \
- &counters[hicnb1->face_dpo_id.dpoi_index \
- * HICN_N_COUNTER], thread_index,\
- HICN_FACE_COUNTERS_DATA_RX, \
- 1, \
- vlib_buffer_length_in_chain(vm, b1)); \
- } \
- \
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && \
- (b0->flags & VLIB_BUFFER_IS_TRACED))) \
- { \
- TRACE_INPUT_PKT_UDP##ipv *t = \
- vlib_add_trace (vm, node, b0, sizeof (*t)); \
- t->pkt_type = HICN_PKT_TYPE_CONTENT; \
- 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), \
- sizeof (t->packet_data)); \
- } \
- \
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && \
- (b1->flags & VLIB_BUFFER_IS_TRACED))) \
- { \
- TRACE_INPUT_PKT_UDP##ipv *t = \
- vlib_add_trace (vm, node, b1, sizeof (*t)); \
- t->pkt_type = HICN_PKT_TYPE_CONTENT; \
- 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), \
- sizeof (t->packet_data)); \
- } \
- \
- \
- /* Verify speculative enqueue, 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(0) \
-
-static uword
-hicn_face_udp4_input_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- u32 n_left_from, *from, *to_next, next_index;
-
- from = vlib_frame_vector_args (frame);
- n_left_from = frame->n_vectors;
- next_index = node->cached_next_index;
- vl_api_hicn_api_node_stats_get_reply_t stats = { 0 };
- u32 thread_index = vm->thread_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);
-
- /* Dual loop, X2 */
- while (n_left_from >= 4 && n_left_to_next >= 2)
- {
- face_input_x2 (4);
- }
-
- /* Dual loop, X1 */
- while (n_left_from > 0 && n_left_to_next > 0)
- {
- face_input_x1 (4);
- }
- vlib_put_next_frame (vm, node, next_index, n_left_to_next);
- }
-
- vlib_node_increment_counter (vm, node->node_index,
- HICNFWD_ERROR_DATAS, stats.pkts_data_count);
-
- return (frame->n_vectors);
-}
-
-/* packet trace format function */
-static u8 *
-hicn_face_udp4_input_format_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 *);
- hicn_face_udp4_input_trace_t *t =
- va_arg (*args, hicn_face_udp4_input_trace_t *);
-
- s =
- format (s, "FACE_UDP4_INPUT: pkt: %d, sw_if_index %d, next index %d\n%U",
- (int) t->pkt_type, t->sw_if_index, t->next_index,
- (t->packet_data[0] & 0xf0) ==
- 0x40 ? format_ip4_header : format_ip6_header, t->packet_data,
- sizeof (t->packet_data));
- return (s);
-}
-
-/*
- * Node registration for the interest forwarder node
- */
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (hicn_face_udp4_input_node) =
-{
- .function = hicn_face_udp4_input_node_fn,
- .name = "hicn-face-udp4-input",
- .vector_size = sizeof (u32),
- .format_trace = hicn_face_udp4_input_format_trace,
- .type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN (hicn_face_udp4_input_error_strings),
- .error_strings = hicn_face_udp4_input_error_strings,
- .n_next_nodes = HICN_FACE_UDP4_INPUT_N_NEXT,
- /* edit / add dispositions here */
- .next_nodes =
- {
- [HICN_FACE_UDP4_INPUT_NEXT_DATA] = "hicn-data-pcslookup",
- [HICN_FACE_UDP4_INPUT_NEXT_MAPME] = "hicn-mapme-ack",
- [HICN_FACE_UDP4_INPUT_NEXT_ERROR_DROP] = "error-drop",
- },
-};
-/* *INDENT-ON* */
-
-
-static uword
-hicn_face_udp6_input_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- u32 n_left_from, *from, *to_next, next_index;
-
- from = vlib_frame_vector_args (frame);
- n_left_from = frame->n_vectors;
- next_index = node->cached_next_index;
- vl_api_hicn_api_node_stats_get_reply_t stats = { 0 };
- u32 thread_index = vm->thread_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);
-
- /* Dual loop, X2 */
- while (n_left_from >= 4 && n_left_to_next >= 2)
- {
- face_input_x2 (6);
- }
-
- /* Dual loop, X1 */
- while (n_left_from > 0 && n_left_to_next > 0)
- {
- face_input_x1 (6);
- }
- vlib_put_next_frame (vm, node, next_index, n_left_to_next);
- }
-
- vlib_node_increment_counter (vm, node->node_index,
- HICNFWD_ERROR_PROCESSED, stats.pkts_processed);
-
- vlib_node_increment_counter (vm, node->node_index,
- HICNFWD_ERROR_DATAS, stats.pkts_data_count);
-
- return (frame->n_vectors);
-}
-
-/* packet trace format function */
-static u8 *
-hicn_face_udp6_input_format_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 *);
- hicn_face_udp6_input_trace_t *t =
- va_arg (*args, hicn_face_udp6_input_trace_t *);
-
- s =
- format (s, "FACE_UDP6_INPUT: pkt: %d, sw_if_index %d, next index %d\n%U",
- (int) t->pkt_type, t->sw_if_index, t->next_index,
- (t->packet_data[0] & 0xf0) ==
- 0x40 ? format_ip4_header : format_ip6_header, t->packet_data,
- sizeof (t->packet_data));
- return (s);
-}
-
-/*
- * Node registration for the interest forwarder node
- */
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (hicn_face_udp6_input_node) =
-{
- .function = hicn_face_udp6_input_node_fn,
- .name = "hicn-face-udp6-input",
- .vector_size = sizeof (u32),
- .format_trace = hicn_face_udp6_input_format_trace,
- .type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN (hicn_face_udp6_input_error_strings),
- .error_strings = hicn_face_udp6_input_error_strings,
- .n_next_nodes = HICN_FACE_UDP6_INPUT_N_NEXT,
- /* edit / add dispositions here */
- .next_nodes =
- {
- [HICN_FACE_UDP6_INPUT_NEXT_DATA] = "hicn-data-pcslookup",
- [HICN_FACE_UDP6_INPUT_NEXT_MAPME] = "hicn-mapme-ack",
- [HICN_FACE_UDP6_INPUT_NEXT_ERROR_DROP] = "error-drop",
- },
-};
-/* *INDENT-ON* */
-
-/******* Face Output *******/
-
-always_inline void
-hicn_face_udp4_encap (vlib_main_t * vm,
- vlib_buffer_t * outer_b0,
- hicn_face_t * face, u32 * next)
-{
- u16 old_l0 = 0, new_l0;
- ip_csum_t sum0;
- ip4_header_t *ip0;
- udp_header_t *udp0;
- hicn_face_udp_t *face_udp = (hicn_face_udp_t *) face->data;
-
- /* ip */
- ip0 = vlib_buffer_get_current (outer_b0);
- clib_memcpy (ip0, &(face_udp->hdrs.ip4.ip), sizeof (ip4_header_t) +
- sizeof (udp_header_t));
-
- /* Fix UDP length */
- udp0 = (udp_header_t *) (ip0 + 1);
-
- new_l0 =
- clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, outer_b0) -
- sizeof (*ip0));
- udp0->length = new_l0;
-
- old_l0 = ip0->length;
- ip0->length =
- clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, outer_b0));
-
- sum0 = ip0->checksum;
-
- //old_l0 always 0, see the rewrite setup
- new_l0 = ip0->length;
-
- sum0 = ip_csum_update (sum0, old_l0, new_l0, ip4_header_t,
- length /* changed member */ );
- ip0->checksum = sum0;
-
- int is_iface = 0;
- ip_adjacency_t *adj;
- if (PREDICT_FALSE (face->shared.adj == ~0))
- is_iface = 1;
- else
- adj = adj_get (face->shared.adj);
-
- /* In case the adj is not complete, we look if a better one exists, otherwise we send an arp request
- * This is necessary to account for the case in which when we create a face, there isn't a /128(/32) adjacency and we match with a more general route which is in glean state
- * In this case in fact, the general route will not be update upone receiving of a arp or neighbour responde, but a new /128(/32) will be created
- */
- if (PREDICT_FALSE
- (is_iface || adj->lookup_next_index < IP_LOOKUP_NEXT_REWRITE))
- {
- fib_prefix_t fib_pfx;
- fib_node_index_t fib_entry_index;
- ip46_address_t ip46 =
- to_ip46 (0, (u8 *) & (face_udp->hdrs.ip4.ip.dst_address));
- fib_prefix_from_ip46_addr (&ip46, &fib_pfx);
- fib_pfx.fp_len = 32;
-
- u32 fib_index = fib_table_find_or_create_and_lock (fib_pfx.fp_proto,
- HICN_FIB_TABLE,
- FIB_SOURCE_PRIORITY_HI);
-
- fib_entry_index = fib_table_lookup (fib_index, &fib_pfx);
-
- face->shared.adj = fib_entry_get_adj (fib_entry_index);
- face->shared.flags &= ~HICN_FACE_FLAGS_IFACE;
- face->shared.flags |= HICN_FACE_FLAGS_FACE;
-
- adj = adj_get (face->shared.adj);
- }
-
- vnet_buffer (outer_b0)->ip.adj_index[VLIB_TX] = face->shared.adj;
- *next = adj->lookup_next_index;
-}
-
-always_inline void
-hicn_face_udp6_encap (vlib_main_t * vm,
- vlib_buffer_t * outer_b0,
- hicn_face_t * face, u32 * next)
-{
- int bogus0;
- u16 new_l0;
- ip6_header_t *ip0;
- udp_header_t *udp0;
- hicn_face_udp_t *face_udp = (hicn_face_udp_t *) face->data;
-
- /* ip */
- ip0 = vlib_buffer_get_current (outer_b0);
- clib_memcpy (ip0, &(face_udp->hdrs.ip6.ip), sizeof (ip6_header_t) +
- sizeof (udp_header_t));
- new_l0 = clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, outer_b0)
- - sizeof (*ip0));
- ip0->payload_length = new_l0;
-
- /* Fix UDP length */
- udp0 = (udp_header_t *) (ip0 + 1);
- udp0->length = new_l0;
-
- udp0->checksum =
- ip6_tcp_udp_icmp_compute_checksum (vm, outer_b0, ip0, &bogus0);
-
- ASSERT (bogus0 == 0);
-
- if (udp0->checksum == 0)
- udp0->checksum = 0xffff;
-
- int is_iface = 0;
- ip_adjacency_t *adj;
- if (PREDICT_FALSE (face->shared.adj == ~0))
- is_iface = 1;
- else
- adj = adj_get (face->shared.adj);
-
- /* In case the adj is not complete, we look if a better one exists, otherwise we send an arp request
- * This is necessary to account for the case in which when we create a face, there isn't a /128(/32) adjacency and we match with a more general route which is in glean state
- * In this case in fact, the general route will not be update upone receiving of a arp or neighbour responde, but a new /128(/32) will be created
- */
- if (PREDICT_FALSE (is_iface || adj->lookup_next_index < IP_LOOKUP_NEXT_REWRITE))
- {
- fib_prefix_t fib_pfx;
- fib_node_index_t fib_entry_index;
- ip46_address_t ip46 =
- to_ip46 (1, (u8 *) & (face_udp->hdrs.ip6.ip.dst_address));
- fib_prefix_from_ip46_addr (&ip46, &fib_pfx);
- fib_pfx.fp_len = 128;
-
- u32 fib_index = fib_table_find_or_create_and_lock (fib_pfx.fp_proto,
- HICN_FIB_TABLE,
- FIB_SOURCE_PRIORITY_HI);
-
- fib_entry_index = fib_table_lookup (fib_index, &fib_pfx);
-
- face->shared.adj = fib_entry_get_adj (fib_entry_index);
- face->shared.flags &= ~HICN_FACE_FLAGS_IFACE;
- face->shared.flags |= HICN_FACE_FLAGS_FACE;
-
- adj = adj_get (face->shared.adj);
- }
-
- vnet_buffer (outer_b0)->ip.adj_index[VLIB_TX] = face->shared.adj;
-
- *next = adj->lookup_next_index;
-}
-
-static char *hicn_face_udp4_output_error_strings[] = {
-#define _(sym, string) string,
- foreach_hicnfwd_error
-#undef _
-};
-
-static char *hicn_face_udp6_output_error_strings[] = {
-#define _(sym, string) string,
- foreach_hicnfwd_error
-#undef _
-};
-
-
-/* Trace context struct */
-typedef struct
-{
- u32 next_index;
- u32 sw_if_index;
- u8 pkt_type;
- u8 packet_data[60];
-}
-hicn_face_udp4_output_trace_t;
-
-/* Trace context struct */
-typedef struct
-{
- u32 next_index;
- u32 sw_if_index;
- u8 pkt_type;
- u8 packet_data[60];
-}
-hicn_face_udp6_output_trace_t;
-
-#define HICN_FACE_UDP_ENCAP_IP4 hicn_face_udp4_encap
-#define HICN_FACE_UDP_ENCAP_IP6 hicn_face_udp6_encap
-
-#define TRACE_OUTPUT_PKT_UDP4 hicn_face_udp4_output_trace_t
-#define TRACE_OUTPUT_PKT_UDP6 hicn_face_udp6_output_trace_t
-
-#define IP_HEADER_4 ip4_header_t
-#define IP_HEADER_6 ip6_header_t
-
-#define face_output_x1(ipv) \
- do { \
- vlib_buffer_t *b0; \
- u32 bi0; \
- u32 next0 = IP_LOOKUP_NEXT_DROP; \
- hicn_face_t * face; \
- \
- /* 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, STORE); \
- CLIB_PREFETCH (b1->data, CLIB_CACHE_LINE_BYTES , LOAD); \
- } \
- /* Dequeue a packet buffer */ \
- bi0 = from[0]; \
- from += 1; \
- n_left_from -= 1; \
- \
- b0 = vlib_get_buffer (vm, bi0); \
- hicn_face_id_t face_id = vnet_buffer (b0)->ip.adj_index[VLIB_TX]; \
- face = \
- hicn_dpoi_get_from_idx(face_id); \
- \
- if (PREDICT_TRUE(face != NULL)) \
- { \
- /* Adjust vlib buffer. Create space for the udp tunnel. */ \
- vlib_buffer_advance(b0, -(sizeof (IP_HEADER_##ipv) + \
- sizeof (udp_header_t))); \
- \
- \
- HICN_FACE_UDP_ENCAP_IP##ipv \
- (vm, b0, face, &next0); \
- stats.pkts_interest_count += 1; \
- vlib_increment_combined_counter ( \
- &counters[face_id * HICN_N_COUNTER], \
- thread_index, \
- HICN_FACE_COUNTERS_INTEREST_TX, \
- 1, \
- vlib_buffer_length_in_chain(vm, b0));\
- } \
- \
- \
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && \
- (b0->flags & VLIB_BUFFER_IS_TRACED))) \
- { \
- TRACE_OUTPUT_PKT_UDP##ipv *t = \
- vlib_add_trace (vm, node, b0, sizeof (*t)); \
- t->pkt_type = HICN_PKT_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) + \
- SIZE_HICN_HEADER##ipv, \
- sizeof (t->packet_data)); \
- } \
- \
- to_next[0] = bi0; \
- to_next += 1; \
- n_left_to_next -= 1; \
- \
- \
- /* 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); \
- } while(0) \
-
-
-#define face_output_x2(ipv) \
- do { \
- vlib_buffer_t *b0, *b1; \
- u32 bi0, bi1; \
- u32 next0 = IP_LOOKUP_NEXT_DROP; \
- u32 next1 = IP_LOOKUP_NEXT_DROP; \
- hicn_face_t *face0, *face1; \
- \
- /* Prefetch for next iteration. */ \
- { \
- vlib_buffer_t *b2, *b3; \
- b2 = vlib_get_buffer (vm, from[2]); \
- b3 = vlib_get_buffer (vm, from[3]); \
- CLIB_PREFETCH (b2, CLIB_CACHE_LINE_BYTES, STORE); \
- CLIB_PREFETCH (b3, CLIB_CACHE_LINE_BYTES, STORE); \
- CLIB_PREFETCH (b2->data, CLIB_CACHE_LINE_BYTES , LOAD); \
- CLIB_PREFETCH (b3->data, CLIB_CACHE_LINE_BYTES , LOAD); \
- } \
- \
- /* Dequeue a packet buffer */ \
- bi0 = from[0]; \
- bi1 = from[1]; \
- from += 2; \
- n_left_from -= 2; \
- to_next[0] = bi0; \
- to_next[1] = bi1; \
- to_next += 2; \
- n_left_to_next -= 2; \
- \
- b0 = vlib_get_buffer (vm, bi0); \
- b1 = vlib_get_buffer (vm, bi1); \
- \
- hicn_face_id_t face_id0 = vnet_buffer (b0)->ip.adj_index[VLIB_TX]; \
- hicn_face_id_t face_id1 = vnet_buffer (b1)->ip.adj_index[VLIB_TX]; \
- face0 = \
- hicn_dpoi_get_from_idx(vnet_buffer (b0)->ip.adj_index[VLIB_TX]); \
- face1 = \
- hicn_dpoi_get_from_idx(vnet_buffer (b1)->ip.adj_index[VLIB_TX]); \
- \
- if (PREDICT_TRUE(face0 != NULL)) \
- { \
- /* Adjust vlib buffer. Create space for the udp tunnel. */ \
- vlib_buffer_advance(b0, -(sizeof (IP_HEADER_##ipv) + \
- sizeof (udp_header_t))); \
- \
- \
- HICN_FACE_UDP_ENCAP_IP##ipv \
- (vm, b0, face0, &next0); \
- stats.pkts_interest_count += 1; \
- vlib_increment_combined_counter ( \
- &counters[face_id0 * HICN_N_COUNTER], \
- thread_index, \
- HICN_FACE_COUNTERS_INTEREST_TX, \
- 1, \
- vlib_buffer_length_in_chain(vm, b0)); \
- } \
- \
- if (PREDICT_TRUE(face1 != NULL)) \
- { \
- /* Adjust vlib buffer. Create space for the udp tunnel. */ \
- vlib_buffer_advance(b1, -(sizeof (IP_HEADER_##ipv) + \
- sizeof (udp_header_t))); \
- \
- \
- HICN_FACE_UDP_ENCAP_IP##ipv \
- (vm, b1, face1, &next1); \
- stats.pkts_interest_count += 1; \
- vlib_increment_combined_counter ( \
- &counters[face_id1 * HICN_N_COUNTER], \
- thread_index, \
- HICN_FACE_COUNTERS_INTEREST_TX, \
- 1, \
- vlib_buffer_length_in_chain(vm, b1)); \
- } \
- \
- \
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && \
- (b0->flags & VLIB_BUFFER_IS_TRACED))) \
- { \
- TRACE_OUTPUT_PKT_UDP##ipv *t = \
- vlib_add_trace (vm, node, b0, sizeof (*t)); \
- t->pkt_type = HICN_PKT_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) + \
- SIZE_HICN_HEADER##ipv, \
- sizeof (t->packet_data)); \
- } \
- \
- \
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && \
- (b1->flags & VLIB_BUFFER_IS_TRACED))) \
- { \
- TRACE_OUTPUT_PKT_UDP##ipv *t = \
- vlib_add_trace (vm, node, b0, sizeof (*t)); \
- t->pkt_type = HICN_PKT_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) + \
- SIZE_HICN_HEADER##ipv, \
- sizeof (t->packet_data)); \
- } \
- /* Verify speculative enqueue, 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(0) \
-
-
-static uword
-hicn_face_udp4_output_node_fn (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- u32 n_left_from, *from, *to_next, 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;
- 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);
-
- /* Dual loop, X2 */
- while (n_left_from >= 4 && n_left_to_next >= 2)
- {
- face_output_x2 (4);
- }
-
- /* Dual loop, X1 */
- while (n_left_from > 0 && n_left_to_next > 0)
- {
- face_output_x1 (4);
- }
- vlib_put_next_frame (vm, node, next_index, n_left_to_next);
- }
-
- vlib_node_increment_counter (vm, node->node_index,
- HICNFWD_ERROR_INTERESTS,
- stats.pkts_interest_count);
-
- return (frame->n_vectors);
-}
-
-/* packet trace format function */
-static u8 *
-hicn_face_udp4_output_format_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 *);
- hicn_face_udp4_output_trace_t *t =
- va_arg (*args, hicn_face_udp4_output_trace_t *);
-
- s =
- format (s, "FACE_UDP4_OUTPUT: pkt: %d, sw_if_index %d, next index %d\n%U",
- (int) t->pkt_type, t->sw_if_index, t->next_index,
- (t->packet_data[0] & 0xf0) ==
- 0x40 ? format_ip4_header : format_ip6_header, t->packet_data,
- sizeof (t->packet_data));
- return (s);
-}
-
-/* *INDENT-OFF* */
-/*
- * Node registration for the interest forwarder node
- */
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (hicn_face_udp4_output_node) =
-{
- .function = hicn_face_udp4_output_node_fn,
- .name = "hicn-face-udp4-output",
- .vector_size = sizeof (u32),
- .format_trace = hicn_face_udp4_output_format_trace,
- .type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN (hicn_face_udp4_output_error_strings),
- .error_strings = hicn_face_udp4_output_error_strings,
- .n_next_nodes = IP4_LOOKUP_N_NEXT,
- /* Reusing the list of nodes from lookup to be compatible with arp */
- .next_nodes = IP4_LOOKUP_NEXT_NODES,
-};
-/* *INDENT-ON* */
-
-/* *INDENT-ON* */
-
-static uword
-hicn_face_udp6_output_node_fn (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- u32 n_left_from, *from, *to_next, 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;
- 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);
-
- /* Dual loop, X2 */
- while (n_left_from >= 4 && n_left_to_next >= 2)
- {
- face_output_x2 (6);
- }
-
- while (n_left_from > 0 && n_left_to_next > 0)
- {
- face_output_x1 (6);
- }
- vlib_put_next_frame (vm, node, next_index, n_left_to_next);
- }
-
- vlib_node_increment_counter (vm, node->node_index,
- HICNFWD_ERROR_INTERESTS,
- stats.pkts_interest_count);
-
- return (frame->n_vectors);
-}
-
-/* packet trace format function */
-static u8 *
-hicn_face_udp6_output_format_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 *);
- hicn_face_udp6_output_trace_t *t =
- va_arg (*args, hicn_face_udp6_output_trace_t *);
-
- s =
- format (s, "FACE_UDP6_OUTPUT: pkt: %d, sw_if_index %d, next index %d\n%u",
- (int) t->pkt_type, t->sw_if_index, t->next_index,
- (t->packet_data[0] & 0xf0) ==
- 0x40 ? format_ip4_header : format_ip6_header, t->packet_data,
- sizeof (t->packet_data));
- return (s);
-}
-
-/* *INDENT-OFF* */
-/*
- * Node registration for the interest forwarder node
- */
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (hicn_face_udp6_output_node) =
-{
- .function = hicn_face_udp6_output_node_fn,
- .name = "hicn-face-udp6-output",
- .vector_size = sizeof (u32),
- .format_trace = hicn_face_udp6_output_format_trace,
- .type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN (hicn_face_udp6_output_error_strings),
- .error_strings = hicn_face_udp6_output_error_strings,
- .n_next_nodes = IP6_LOOKUP_N_NEXT,
- /* Reusing the list of nodes from lookup to be compatible with neighbour discovery */
- .next_nodes = IP6_LOOKUP_NEXT_NODES,
-};
-/* *INDENT-ON* */
-
-/* *INDENT-ON* */
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/hicn-plugin/src/faces/udp/face_udp_node.h b/hicn-plugin/src/faces/udp/face_udp_node.h
deleted file mode 100644
index c759312c8..000000000
--- a/hicn-plugin/src/faces/udp/face_udp_node.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2017-2019 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_UDP_NODE_H__
-#define __HICN_FACE_UDP_NODE_H__
-
-#include <vlib/vlib.h>
-#include <vnet/vnet.h>
-
-extern vlib_node_registration_t hicn_face_udp4_input_node;
-extern vlib_node_registration_t hicn_face_udp6_input_node;
-extern vlib_node_registration_t hicn_face_udp4_output_node;
-extern vlib_node_registration_t hicn_face_udp6_output_node;
-
-#endif // __HICN_FACE_UDP_NODE_H__
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/hicn-plugin/src/faces/udp/iface_udp_node.c b/hicn-plugin/src/faces/udp/iface_udp_node.c
deleted file mode 100644
index 1fdd68f0b..000000000
--- a/hicn-plugin/src/faces/udp/iface_udp_node.c
+++ /dev/null
@@ -1,987 +0,0 @@
-/*
- * Copyright (c) 2017-2019 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 "iface_udp_node.h"
-#include "dpo_udp.h"
-#include "../face.h"
-
-#include "../../infra.h"
-#include "../../hicn.h"
-
-/**
- * @File
- *
- * Definition of the nodes for udp incomplete faces.
- */
-
-vlib_node_registration_t hicn_iface_udp4_input_node;
-vlib_node_registration_t hicn_iface_udp6_input_node;
-vlib_node_registration_t hicn_iface_udp4_output_node;
-vlib_node_registration_t hicn_iface_udp6_output_node;
-
-u32 data_fwd_face_udp4_vlib_edge;
-u32 data_fwd_face_udp6_vlib_edge;
-
-void
-hicn_iface_udp_init (vlib_main_t * vm)
-{
- data_fwd_face_udp4_vlib_edge = vlib_node_add_next (vm,
- hicn_data_fwd_node.index,
- hicn_iface_udp4_output_node.index);
-
- data_fwd_face_udp6_vlib_edge = vlib_node_add_next (vm,
- hicn_data_fwd_node.index,
- hicn_iface_udp6_output_node.index);
-
- u32 temp_index4 = vlib_node_add_next (vm,
- hicn_interest_hitcs_node.index,
- hicn_iface_udp4_output_node.index);
- u32 temp_index6 = vlib_node_add_next (vm,
- hicn_interest_hitcs_node.index,
- hicn_iface_udp6_output_node.index);
-
- ASSERT (temp_index4 == data_fwd_face_udp4_vlib_edge);
- ASSERT (temp_index6 == data_fwd_face_udp6_vlib_edge);
-}
-
-static char *hicn_iface_udp4_input_error_strings[] = {
-#define _(sym, string) string,
- foreach_hicnfwd_error
-#undef _
-};
-
-static char *hicn_iface_udp6_input_error_strings[] = {
-#define _(sym, string) string,
- foreach_hicnfwd_error
-#undef _
-};
-
-u32
-get_face_udp4_output_node (void)
-{
- return data_fwd_face_udp4_vlib_edge;
-}
-
-u32
-get_face_udp6_output_node (void)
-{
- return data_fwd_face_udp6_vlib_edge;
-}
-
-/* Trace context struct */
-typedef struct
-{
- u32 next_index;
- u32 sw_if_index;
- u8 pkt_type;
- u8 packet_data[60];
-}
-hicn_iface_udp4_input_trace_t;
-
-typedef enum
-{
- HICN_IFACE_UDP4_INPUT_NEXT_INTEREST,
- HICN_IFACE_UDP4_INPUT_NEXT_MAPME,
- HICN_IFACE_UDP4_INPUT_NEXT_ERROR_DROP,
- HICN_IFACE_UDP4_INPUT_N_NEXT,
-} hicn_iface_udp4_input_next_t;
-
-/* Trace context struct */
-typedef struct
-{
- u32 next_index;
- u32 sw_if_index;
- u8 pkt_type;
- u8 packet_data[60];
-}
-hicn_iface_udp6_input_trace_t;
-
-typedef enum
-{
- HICN_IFACE_UDP6_INPUT_NEXT_INTEREST,
- HICN_IFACE_UDP6_INPUT_NEXT_MAPME,
- HICN_IFACE_UDP6_INPUT_NEXT_ERROR_DROP,
- HICN_IFACE_UDP6_INPUT_N_NEXT,
-} hicn_iface_udp6_input_next_t;
-
-#define ERROR_INPUT_UDP4 HICN_IFACE_UDP4_INPUT_NEXT_ERROR_DROP
-#define ERROR_INPUT_UDP6 HICN_IFACE_UDP6_INPUT_NEXT_ERROR_DROP
-
-#define IP_HEADER_4 ip4_header_t
-#define IP_HEADER_6 ip6_header_t
-
-#define NEXT_MAPME_UDP4 HICN_IFACE_UDP4_INPUT_NEXT_MAPME
-#define NEXT_MAPME_UDP6 HICN_IFACE_UDP6_INPUT_NEXT_MAPME
-
-#define NEXT_INTEREST_UDP4 HICN_IFACE_UDP4_INPUT_NEXT_INTEREST
-#define NEXT_INTEREST_UDP6 HICN_IFACE_UDP6_INPUT_NEXT_INTEREST
-
-#define HICN_IFACE_UDP_ADD_LOCK_IP4 hicn_dpo_udp4_add_and_lock
-#define HICN_IFACE_UDP_ADD_LOCK_IP6 hicn_dpo_udp6_add_and_lock
-
-#define GET_FACE_UDP4 get_face_udp4_output_node
-#define GET_FACE_UDP6 get_face_udp6_output_node
-
-#define TRACE_INPUT_PKT_UDP4 hicn_iface_udp4_input_trace_t
-#define TRACE_INPUT_PKT_UDP6 hicn_iface_udp6_input_trace_t
-
-#define iface_input_x1(ipv) \
- do { \
- vlib_buffer_t *b0; \
- u32 bi0; \
- u32 next0 = ERROR_INPUT_UDP##ipv; \
- IP_HEADER_##ipv * ip_hdr = NULL; \
- u8 * inner_ip_hdr = NULL; \
- udp_header_t * udp_hdr = NULL; \
- hicn_buffer_t * hicnb0; \
- /* 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, STORE); \
- CLIB_PREFETCH (b1->data, CLIB_CACHE_LINE_BYTES , LOAD); \
- } \
- /* Dequeue a packet buffer */ \
- bi0 = from[0]; \
- from += 1; \
- n_left_from -= 1; \
- to_next[0] = bi0; \
- to_next += 1; \
- n_left_to_next -= 1; \
- \
- b0 = vlib_get_buffer (vm, bi0); \
- ip_hdr = (IP_HEADER_##ipv *) vlib_buffer_get_current(b0); \
- udp_hdr = (udp_header_t *) (ip_hdr + 1); \
- hicnb0 = hicn_get_buffer(b0); \
- \
- stats.pkts_interest_count += 1; \
- \
- inner_ip_hdr = (u8 *)(udp_hdr + 1); \
- u8 is_v6 = hicn_is_v6((hicn_header_t *)inner_ip_hdr); \
- u8 is_icmp = is_v6*(inner_ip_hdr[6] == IPPROTO_ICMPV6) + \
- (1 - is_v6)*(inner_ip_hdr[9] == IPPROTO_ICMPV4); \
- \
- next0 = is_icmp*NEXT_MAPME_UDP##ipv + \
- (1-is_icmp)*NEXT_INTEREST_UDP##ipv; \
- \
- HICN_IFACE_UDP_ADD_LOCK_IP##ipv \
- (&(hicnb0->face_dpo_id), \
- &(ip_hdr->dst_address), \
- &(ip_hdr->src_address), \
- udp_hdr->dst_port, \
- udp_hdr->src_port, \
- GET_FACE_UDP##ipv \
- (), \
- &hicnb0->flags, \
- vnet_buffer(b0)->sw_if_index[VLIB_RX]); \
- \
- vlib_buffer_advance(b0, sizeof(IP_HEADER_##ipv) + \
- sizeof(udp_header_t)); \
- \
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && \
- (b0->flags & VLIB_BUFFER_IS_TRACED))) \
- { \
- TRACE_INPUT_PKT_UDP##ipv *t = \
- vlib_add_trace (vm, node, b0, sizeof (*t)); \
- t->pkt_type = HICN_PKT_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), \
- sizeof (t->packet_data)); \
- } \
- \
- vlib_increment_combined_counter ( \
- &counters[hicnb0->face_dpo_id.dpoi_index \
- * HICN_N_COUNTER], thread_index,\
- HICN_FACE_COUNTERS_INTEREST_RX, \
- 1, \
- vlib_buffer_length_in_chain(vm, b0)); \
- \
- \
- /* 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); \
- }while(0)
-
-
-#define iface_input_x2(ipv) \
- do { \
- vlib_buffer_t *b0, *b1; \
- u32 bi0, bi1; \
- u32 next0, next1 = ERROR_INPUT_UDP##ipv; \
- IP_HEADER_##ipv * ip_hdr0 = NULL, *ip_hdr1 = NULL; \
- u8 * inner_ip_hdr0 = NULL, *inner_ip_hdr1 = NULL; \
- udp_header_t * udp_hdr0 = NULL, *udp_hdr1 = NULL; \
- hicn_buffer_t * hicnb0, *hicnb1; \
- \
- /* Prefetch for next iteration. */ \
- { \
- vlib_buffer_t *b2, *b3; \
- b2 = vlib_get_buffer (vm, from[2]); \
- b3 = vlib_get_buffer (vm, from[3]); \
- CLIB_PREFETCH (b2, CLIB_CACHE_LINE_BYTES, STORE); \
- CLIB_PREFETCH (b3, CLIB_CACHE_LINE_BYTES, STORE); \
- CLIB_PREFETCH (b2->data, CLIB_CACHE_LINE_BYTES , LOAD); \
- CLIB_PREFETCH (b3->data, CLIB_CACHE_LINE_BYTES , LOAD); \
- } \
- \
- /* Dequeue a packet buffer */ \
- bi0 = from[0]; \
- bi1 = from[1]; \
- from += 2; \
- n_left_from -= 2; \
- to_next[0] = bi0; \
- to_next[1] = bi1; \
- to_next += 2; \
- n_left_to_next -= 2; \
- \
- b0 = vlib_get_buffer (vm, bi0); \
- b1 = vlib_get_buffer (vm, bi1); \
- ip_hdr0 = (IP_HEADER_##ipv *) vlib_buffer_get_current(b0); \
- ip_hdr1 = (IP_HEADER_##ipv *) vlib_buffer_get_current(b1); \
- udp_hdr0 = (udp_header_t *) (ip_hdr0 + 1); \
- udp_hdr1 = (udp_header_t *) (ip_hdr1 + 1); \
- hicnb0 = hicn_get_buffer(b0); \
- hicnb1 = hicn_get_buffer(b1); \
- \
- stats.pkts_interest_count += 2; \
- \
- inner_ip_hdr0 = (u8 *)(udp_hdr0 + 1); \
- inner_ip_hdr1 = (u8 *)(udp_hdr1 + 1); \
- u8 is_v6_0 = hicn_is_v6((hicn_header_t *)inner_ip_hdr0); \
- u8 is_v6_1 = hicn_is_v6((hicn_header_t *)inner_ip_hdr1); \
- u8 is_icmp0 = is_v6_0*(inner_ip_hdr0[6] == IPPROTO_ICMPV6) + \
- (1 - is_v6_0)*(inner_ip_hdr0[9] == IPPROTO_ICMPV4); \
- u8 is_icmp1 = is_v6_1*(inner_ip_hdr1[6] == IPPROTO_ICMPV6) + \
- (1 - is_v6_1)*(inner_ip_hdr1[9] == IPPROTO_ICMPV4); \
- \
- next0 = is_icmp0*NEXT_MAPME_UDP##ipv + \
- (1-is_icmp0)*NEXT_INTEREST_UDP##ipv; \
- next1 = is_icmp1*NEXT_MAPME_UDP##ipv + \
- (1-is_icmp1)*NEXT_INTEREST_UDP##ipv; \
- \
- HICN_IFACE_UDP_ADD_LOCK_IP##ipv \
- (&(hicnb0->face_dpo_id), \
- &(ip_hdr0->dst_address), \
- &(ip_hdr0->src_address), \
- udp_hdr0->dst_port, \
- udp_hdr0->src_port, \
- GET_FACE_UDP##ipv \
- (), \
- &hicnb0->flags, \
- vnet_buffer(b0)->sw_if_index[VLIB_RX]); \
- \
- \
- HICN_IFACE_UDP_ADD_LOCK_IP##ipv \
- (&(hicnb1->face_dpo_id), \
- &(ip_hdr1->dst_address), \
- &(ip_hdr1->src_address), \
- udp_hdr1->dst_port, \
- udp_hdr1->src_port, \
- GET_FACE_UDP##ipv \
- (), \
- &hicnb1->flags, \
- vnet_buffer(b1)->sw_if_index[VLIB_RX]); \
- \
- vlib_buffer_advance(b0, sizeof(IP_HEADER_##ipv) + \
- sizeof(udp_header_t)); \
- \
- vlib_buffer_advance(b1, sizeof(IP_HEADER_##ipv) + \
- sizeof(udp_header_t)); \
- \
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && \
- (b0->flags & VLIB_BUFFER_IS_TRACED))) \
- { \
- TRACE_INPUT_PKT_UDP##ipv *t = \
- vlib_add_trace (vm, node, b0, sizeof (*t)); \
- t->pkt_type = HICN_PKT_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), \
- sizeof (t->packet_data)); \
- } \
- \
- \
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && \
- (b1->flags & VLIB_BUFFER_IS_TRACED))) \
- { \
- TRACE_INPUT_PKT_UDP##ipv *t = \
- vlib_add_trace (vm, node, b1, sizeof (*t)); \
- t->pkt_type = HICN_PKT_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), \
- sizeof (t->packet_data)); \
- } \
- \
- vlib_increment_combined_counter ( \
- &counters[hicnb0->face_dpo_id.dpoi_index \
- * HICN_N_COUNTER], thread_index,\
- HICN_FACE_COUNTERS_INTEREST_RX, \
- 1, \
- vlib_buffer_length_in_chain(vm, b0)); \
- \
- vlib_increment_combined_counter ( \
- &counters[hicnb1->face_dpo_id.dpoi_index \
- * HICN_N_COUNTER], thread_index,\
- HICN_FACE_COUNTERS_INTEREST_RX, \
- 1, \
- vlib_buffer_length_in_chain(vm, b1)); \
- \
- /* Verify speculative enqueue, 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(0)
-
-
-static uword
-hicn_iface_udp4_input_node_fn (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- u32 n_left_from, *from, *to_next, 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;
- 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);
-
- /* Dual loop, X2 */
- while (n_left_from >= 4 && n_left_to_next >= 2)
- {
- iface_input_x2 (4);
- }
-
- /* Dual loop, X1 */
- while (n_left_from > 0 && n_left_to_next > 0)
- {
- iface_input_x1 (4);
- }
- vlib_put_next_frame (vm, node, next_index, n_left_to_next);
- }
-
- vlib_node_increment_counter (vm, node->node_index,
- HICNFWD_ERROR_INTERESTS,
- stats.pkts_interest_count);
-
- return (frame->n_vectors);
-}
-
-/* packet trace format function */
-static u8 *
-hicn_iface_udp4_input_format_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 *);
- hicn_iface_udp4_input_trace_t *t =
- va_arg (*args, hicn_iface_udp4_input_trace_t *);
-
- s =
- format (s, "IFACE_UDP4_INPUT: pkt: %d, sw_if_index %d, next index %d\n%U",
- (int) t->pkt_type, t->sw_if_index, t->next_index,
- (t->packet_data[0] & 0xf0) ==
- 0x40 ? format_ip4_header : format_ip6_header, t->packet_data,
- sizeof (t->packet_data));
- return (s);
-}
-
-/*
- * Node registration for the interest forwarder node
- */
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (hicn_iface_udp4_input_node) =
-
-{
- .function = hicn_iface_udp4_input_node_fn,
- .name = "hicn-iface-udp4-input",
- .vector_size = sizeof (u32),
- .format_trace = hicn_iface_udp4_input_format_trace,
- .type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN (hicn_iface_udp4_input_error_strings),
- .error_strings = hicn_iface_udp4_input_error_strings,
- .n_next_nodes = HICN_IFACE_UDP4_INPUT_N_NEXT,
- .next_nodes =
- {
- [HICN_IFACE_UDP4_INPUT_NEXT_INTEREST] = "hicn-interest-pcslookup",
- [HICN_IFACE_UDP4_INPUT_NEXT_MAPME] = "hicn-mapme-ctrl",
- [HICN_IFACE_UDP4_INPUT_NEXT_ERROR_DROP] = "error-drop",
- },
-};
-/* *INDENT-ON* */
-
-
-static uword
-hicn_iface_udp6_input_node_fn (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- u32 n_left_from, *from, *to_next, 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;
- 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);
-
- /* Dual loop, X2 */
- while (n_left_from >= 4 && n_left_to_next >= 2)
- {
- iface_input_x2 (6);
- }
-
- /* Dual loop, X1 */
- while (n_left_from > 0 && n_left_to_next > 0)
- {
- iface_input_x1 (6);
- }
- vlib_put_next_frame (vm, node, next_index, n_left_to_next);
- }
-
- vlib_node_increment_counter (vm, node->node_index,
- HICNFWD_ERROR_INTERESTS,
- stats.pkts_interest_count);
-
- return (frame->n_vectors);
-}
-
-/* packet trace format function */
-static u8 *
-hicn_iface_udp6_input_format_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 *);
- hicn_iface_udp6_input_trace_t *t =
- va_arg (*args, hicn_iface_udp6_input_trace_t *);
-
- s =
- format (s, "IFACE_UDP6_INPUT: pkt: %d, sw_if_index %d, next index %d\n%U",
- (int) t->pkt_type, t->sw_if_index, t->next_index,
- (t->packet_data[0] & 0xf0) ==
- 0x40 ? format_ip4_header : format_ip6_header, t->packet_data,
- sizeof (t->packet_data));
- return (s);
-}
-
-/*
- * Node registration for the interest forwarder node
- */
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (hicn_iface_udp6_input_node) =
-{
- .function = hicn_iface_udp6_input_node_fn,
- .name = "hicn-iface-udp6-input",
- .vector_size = sizeof (u32),
- .format_trace = hicn_iface_udp6_input_format_trace,
- .type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN (hicn_iface_udp6_input_error_strings),
- .error_strings = hicn_iface_udp6_input_error_strings,
- .n_next_nodes = HICN_IFACE_UDP6_INPUT_N_NEXT,
- .next_nodes =
- {
- [HICN_IFACE_UDP6_INPUT_NEXT_INTEREST] = "hicn-interest-pcslookup",
- [HICN_IFACE_UDP6_INPUT_NEXT_MAPME] = "hicn-mapme-ctrl",
- [HICN_IFACE_UDP6_INPUT_NEXT_ERROR_DROP] = "error-drop",
- },
-};
-/* *INDENT-ON* */
-
-/******* Iface Output *******/
-
-always_inline void
-hicn_iface_udp4_encap (vlib_main_t * vm,
- vlib_buffer_t * b0, hicn_face_t * face)
-{
- u16 new_l0 = 0;
- ip4_header_t *ip0;
- udp_header_t *udp0;
- hicn_face_udp_t *face_udp = (hicn_face_udp_t *) face->data;
-
- /* Adjust vlib buffers */
- /* Set the right length on the header buffer */
- /* Move the next buffer current data pointer back to the ip+tcp header (hicn header) */
- word offset = sizeof (ip4_header_t) + sizeof (udp_header_t);
- vlib_buffer_advance (b0, -offset);
-
- /* ip */
- ip0 = vlib_buffer_get_current (b0);
- clib_memcpy (ip0, &(face_udp->hdrs.ip4.ip), sizeof (ip4_header_t) +
- sizeof (udp_header_t));
-
- /* Fix UDP length */
- udp0 = (udp_header_t *) (ip0 + 1);
-
- new_l0 =
- clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b0) -
- sizeof (*ip0));
- udp0->length = new_l0;
-
- ip0->length = clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b0));
- ip0->checksum = ip4_header_checksum (ip0);
-}
-
-always_inline void
-hicn_iface_udp6_encap (vlib_main_t * vm,
- vlib_buffer_t * b0, hicn_face_t * face)
-{
- int bogus0;
- u16 new_l0;
- ip6_header_t *ip0;
- udp_header_t *udp0;
- hicn_face_udp_t *face_udp = (hicn_face_udp_t *) face->data;
-
- /* Adjust vlib buffer */
- word offset = sizeof (ip6_header_t) + sizeof (udp_header_t);
- vlib_buffer_advance (b0, -offset);
-
- /* ip */
- ip0 = vlib_buffer_get_current (b0);
- clib_memcpy (ip0, &(face_udp->hdrs.ip6.ip), sizeof (ip6_header_t) +
- sizeof (udp_header_t));
-
- new_l0 = clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b0)
- - sizeof (*ip0));
-
- ip0->payload_length = new_l0;
-
- /* Fix UDP length */
- udp0 = (udp_header_t *) (ip0 + 1);
- udp0->length = new_l0;
-
- udp0->checksum = ip6_tcp_udp_icmp_compute_checksum (vm, b0, ip0, &bogus0);
-
- ASSERT (bogus0 == 0);
-
- if (udp0->checksum == 0)
- udp0->checksum = 0xffff;
-}
-
-static char *hicn_iface_udp4_output_error_strings[] = {
-#define _(sym, string) string,
- foreach_hicnfwd_error
-#undef _
-};
-
-static char *hicn_iface_udp6_output_error_strings[] = {
-#define _(sym, string) string,
- foreach_hicnfwd_error
-#undef _
-};
-
-/* Trace context struct */
-typedef struct
-{
- u32 next_index;
- u32 sw_if_index;
- u8 pkt_type;
- u8 packet_data[60];
-}
-hicn_iface_udp4_output_trace_t;
-
-typedef enum
-{
- HICN_IFACE_UDP4_OUTPUT_NEXT_LOOKUP,
- HICN_IFACE_UDP4_OUTPUT_NEXT_ERROR_DROP,
- HICN_IFACE_UDP4_OUTPUT_N_NEXT,
-} hicn_iface_udp4_output_next_t;
-
-/* Trace context struct */
-typedef struct
-{
- u32 next_index;
- u32 sw_if_index;
- u8 pkt_type;
- u8 packet_data[60];
-}
-hicn_iface_udp6_output_trace_t;
-
-typedef enum
-{
- HICN_IFACE_UDP6_OUTPUT_NEXT_LOOKUP,
- HICN_IFACE_UDP6_OUTPUT_NEXT_ERROR_DROP,
- HICN_IFACE_UDP6_OUTPUT_N_NEXT,
-} hicn_iface_udp6_output_next_t;
-
-#define ERROR_OUTPUT_UDP4 HICN_IFACE_UDP4_OUTPUT_NEXT_ERROR_DROP
-#define ERROR_OUTPUT_UDP6 HICN_IFACE_UDP6_OUTPUT_NEXT_ERROR_DROP
-
-#define IP_HEADER_4 ip4_header_t
-#define IP_HEADER_6 ip6_header_t
-
-#define NEXT_LOOKUP_UDP4 HICN_IFACE_UDP4_OUTPUT_NEXT_LOOKUP
-#define NEXT_LOOKUP_UDP6 HICN_IFACE_UDP6_OUTPUT_NEXT_LOOKUP
-
-#define HICN_IFACE_UDP_ADD_LOCK_IP4 hicn_dpo_udp4_add_and_lock
-#define HICN_IFACE_UDP_ADD_LOCK_IP6 hicn_dpo_udp6_add_and_lock
-
-#define HICN_FACE_UDP_ENCAP_IP4 hicn_iface_udp4_encap
-#define HICN_FACE_UDP_ENCAP_IP6 hicn_iface_udp6_encap
-
-#define TRACE_OUTPUT_PKT_UDP4 hicn_iface_udp4_output_trace_t
-#define TRACE_OUTPUT_PKT_UDP6 hicn_iface_udp6_output_trace_t
-
-#define SIZE_HICN_HEADER4 sizeof(ip4_header_t) + sizeof(udp_header_t)
-#define SIZE_HICN_HEADER6 sizeof(ip6_header_t) + sizeof(udp_header_t)
-
-#define iface_output_x1(ipv) \
- do { \
- vlib_buffer_t *b0; \
- u32 bi0; \
- u32 next0 = ERROR_OUTPUT_UDP##ipv; \
- hicn_face_t * face; \
- \
- /* 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, STORE); \
- CLIB_PREFETCH (b1->data, CLIB_CACHE_LINE_BYTES , LOAD); \
- } \
- /* Dequeue a packet buffer */ \
- bi0 = from[0]; \
- from += 1; \
- n_left_from -= 1; \
- to_next[0] = bi0; \
- to_next += 1; \
- n_left_to_next -= 1; \
- \
- b0 = vlib_get_buffer (vm, bi0); \
- \
- hicn_face_id_t face_id = vnet_buffer (b0)->ip.adj_index[VLIB_TX]; \
- face = \
- hicn_dpoi_get_from_idx(face_id); \
- \
- if (PREDICT_TRUE(face != NULL)) \
- { \
- HICN_FACE_UDP_ENCAP_IP##ipv \
- (vm, b0, face); \
- next0 = NEXT_LOOKUP_UDP##ipv; \
- stats.pkts_data_count += 1; \
- vlib_increment_combined_counter ( \
- &counters[face_id * HICN_N_COUNTER], \
- thread_index, \
- HICN_FACE_COUNTERS_DATA_TX, \
- 1, \
- vlib_buffer_length_in_chain(vm, b0)); \
- } \
- \
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && \
- (b0->flags & VLIB_BUFFER_IS_TRACED))) \
- { \
- TRACE_OUTPUT_PKT_UDP##ipv *t = \
- vlib_add_trace (vm, node, b0, sizeof (*t)); \
- t->pkt_type = HICN_PKT_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) + \
- SIZE_HICN_HEADER##ipv, \
- sizeof (t->packet_data)); \
- } \
- \
- \
- /* 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); \
- } while(0)
-
-#define iface_output_x2(ipv) \
- do { \
- vlib_buffer_t *b0, *b1; \
- u32 bi0, bi1; \
- u32 next0 = ERROR_OUTPUT_UDP##ipv, next1 = ERROR_OUTPUT_UDP##ipv; \
- hicn_face_t *face0, *face1; \
- \
- /* Prefetch for next iteration. */ \
- { \
- vlib_buffer_t *b2, *b3; \
- b2 = vlib_get_buffer (vm, from[2]); \
- b3 = vlib_get_buffer (vm, from[3]); \
- CLIB_PREFETCH (b2, CLIB_CACHE_LINE_BYTES, STORE); \
- CLIB_PREFETCH (b3, CLIB_CACHE_LINE_BYTES, STORE); \
- CLIB_PREFETCH (b2->data, CLIB_CACHE_LINE_BYTES , LOAD); \
- CLIB_PREFETCH (b3->data, CLIB_CACHE_LINE_BYTES , LOAD); \
- } \
- \
- /* Dequeue packets buffers */ \
- bi0 = from[0]; \
- bi1 = from[1]; \
- from += 2; \
- n_left_from -= 2; \
- to_next[0] = bi0; \
- to_next[1] = bi1; \
- to_next += 2; \
- n_left_to_next -= 2; \
- \
- b0 = vlib_get_buffer (vm, bi0); \
- b1 = vlib_get_buffer (vm, bi1); \
- \
- hicn_face_id_t face_id0 = vnet_buffer (b0)->ip.adj_index[VLIB_TX]; \
- hicn_face_id_t face_id1 = vnet_buffer (b1)->ip.adj_index[VLIB_TX]; \
- face0 = \
- hicn_dpoi_get_from_idx(face_id0); \
- face1 = \
- hicn_dpoi_get_from_idx(face_id1); \
- \
- if (PREDICT_TRUE(face0 != NULL)) \
- { \
- HICN_FACE_UDP_ENCAP_IP##ipv \
- (vm, b0, face0); \
- next0 = NEXT_LOOKUP_UDP##ipv; \
- stats.pkts_data_count += 1; \
- vlib_increment_combined_counter ( \
- &counters[face_id0 * HICN_N_COUNTER], \
- thread_index, \
- HICN_FACE_COUNTERS_DATA_TX, \
- 1, \
- vlib_buffer_length_in_chain(vm, b0)); \
- } \
- \
- if (PREDICT_TRUE(face1 != NULL)) \
- { \
- HICN_FACE_UDP_ENCAP_IP##ipv \
- (vm, b1, face1); \
- next1 = NEXT_LOOKUP_UDP##ipv; \
- stats.pkts_data_count += 1; \
- vlib_increment_combined_counter ( \
- &counters[face_id1 * HICN_N_COUNTER], \
- thread_index, \
- HICN_FACE_COUNTERS_DATA_TX, \
- 1, \
- vlib_buffer_length_in_chain(vm, b1)); \
- } \
- \
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && \
- (b0->flags & VLIB_BUFFER_IS_TRACED))) \
- { \
- TRACE_OUTPUT_PKT_UDP##ipv *t = \
- vlib_add_trace (vm, node, b0, sizeof (*t)); \
- t->pkt_type = HICN_PKT_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) + \
- SIZE_HICN_HEADER##ipv, \
- sizeof (t->packet_data)); \
- } \
- \
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && \
- (b1->flags & VLIB_BUFFER_IS_TRACED))) \
- { \
- TRACE_OUTPUT_PKT_UDP##ipv *t = \
- vlib_add_trace (vm, node, b1, sizeof (*t)); \
- t->pkt_type = HICN_PKT_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) + \
- SIZE_HICN_HEADER##ipv, \
- sizeof (t->packet_data)); \
- } \
- \
- \
- /* Verify speculative enqueue, 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(0)
-
-
-static uword
-hicn_iface_udp4_output_node_fn (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- u32 n_left_from, *from, *to_next, 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;
- 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)
- {
- iface_output_x2 (4);
- }
-
- while (n_left_from > 0 && n_left_to_next > 0)
- {
- iface_output_x1 (4);
- }
-
- vlib_put_next_frame (vm, node, next_index, n_left_to_next);
- }
-
- vlib_node_increment_counter (vm, node->node_index,
- HICNFWD_ERROR_DATAS, stats.pkts_data_count);
-
- return (frame->n_vectors);
-}
-
-/* packet trace format function */
-static u8 *
-hicn_iface_udp4_output_format_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 *);
- hicn_iface_udp4_output_trace_t *t =
- va_arg (*args, hicn_iface_udp4_output_trace_t *);
-
- s =
- format (s,
- "IFACE_UDP4_OUTPUT: pkt: %d, out face %d, next index %d\n%U",
- (int) t->pkt_type, t->sw_if_index, t->next_index,
- (t->packet_data[0] & 0xf0) ==
- 0x40 ? format_ip4_header : format_ip6_header, t->packet_data,
- sizeof (t->packet_data));
- return (s);
-}
-
-
-/*
- * Node registration for the interest forwarder node
- */
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (hicn_iface_udp4_output_node) =
-{
- .function = hicn_iface_udp4_output_node_fn,
- .name = "hicn-iface-udp4-output",
- .vector_size = sizeof (u32),
- .format_trace = hicn_iface_udp4_output_format_trace,
- .type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN (hicn_iface_udp4_output_error_strings),
- .error_strings = hicn_iface_udp4_output_error_strings,
- .n_next_nodes = HICN_IFACE_UDP4_OUTPUT_N_NEXT,
- /* edit / add dispositions here */
- .next_nodes =
- {
- [HICN_IFACE_UDP4_OUTPUT_NEXT_LOOKUP] = "ip4-lookup",
- [HICN_IFACE_UDP4_OUTPUT_NEXT_ERROR_DROP] = "error-drop",
- },
-};
-/* *INDENT-ON* */
-
-
-static uword
-hicn_iface_udp6_output_node_fn (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- u32 n_left_from, *from, *to_next, 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;
- 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)
- {
- iface_output_x2 (6);
- }
-
- while (n_left_from > 0 && n_left_to_next > 0)
- {
- iface_output_x1 (6);
- }
-
- vlib_put_next_frame (vm, node, next_index, n_left_to_next);
- }
-
- vlib_node_increment_counter (vm, node->node_index,
- HICNFWD_ERROR_DATAS, stats.pkts_data_count);
-
- return (frame->n_vectors);
-
-}
-
-/* packet trace format function */
-static u8 *
-hicn_iface_udp6_output_format_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 *);
- hicn_iface_udp6_output_trace_t *t =
- va_arg (*args, hicn_iface_udp6_output_trace_t *);
-
- s =
- format (s,
- "IFACE_UDP6_OUTPUT: pkt: %d, out face %d, next index %d\n%U",
- (int) t->pkt_type, t->sw_if_index, t->next_index,
- (t->packet_data[0] & 0xf0) ==
- 0x40 ? format_ip4_header : format_ip6_header, t->packet_data,
- sizeof (t->packet_data));
- return (s);
-}
-
-/*
- * Node registration for the interest forwarder node
- */
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (hicn_iface_udp6_output_node) =
-{
- .function = hicn_iface_udp6_output_node_fn,
- .name = "hicn-iface-udp6-output",
- .vector_size = sizeof (u32),
- .format_trace = hicn_iface_udp6_output_format_trace,
- .type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN (hicn_iface_udp6_output_error_strings),
- .error_strings = hicn_iface_udp6_output_error_strings,
- .n_next_nodes = HICN_IFACE_UDP6_OUTPUT_N_NEXT,
- /* edit / add dispositions here */
- .next_nodes =
- {
- [HICN_IFACE_UDP6_OUTPUT_NEXT_LOOKUP] = "ip6-lookup",
- [HICN_IFACE_UDP6_OUTPUT_NEXT_ERROR_DROP] = "error-drop",
- },
-};
-/* *INDENT-ON* */
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/hicn-plugin/src/faces/udp/iface_udp_node.h b/hicn-plugin/src/faces/udp/iface_udp_node.h
deleted file mode 100644
index 957d19217..000000000
--- a/hicn-plugin/src/faces/udp/iface_udp_node.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2017-2019 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_IFACE_UDP_H__
-#define __HICN_IFACE_UDP_H__
-
-#include <vlib/vlib.h>
-
-extern vlib_node_registration_t hicn_iface_udp4_input_node;
-extern vlib_node_registration_t hicn_iface_udp6_input_node;
-extern vlib_node_registration_t hicn_iface_udp4_output_node;
-extern vlib_node_registration_t hicn_iface_udp6_output_node;
-
-void hicn_iface_udp_init (vlib_main_t * vm);
-
-#endif // __HICN_FACE_UDP_H__
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/hicn-plugin/src/hashtb.h b/hicn-plugin/src/hashtb.h
index 756f247b7..3c72fda65 100644
--- a/hicn-plugin/src/hashtb.h
+++ b/hicn-plugin/src/hashtb.h
@@ -24,47 +24,35 @@
#include "parser.h"
#include "error.h"
-/* Handy abbreviations for success status, and for boolean values */
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-/*
+/**
+ * @file hashtb.h
* Lookup is finding a hashtable record whose name matches the name being
* looked up. Most of the lookup work is based on the hash value of the two
* names. Note that the intel cache line size is 64 bytes, and some platforms
- * load in 2 cache lines together. - first step is to match a record at the
- * bucket/slot level (htab has an array of htbucket_t/htbc_elmt, where each
- * bucket has 7 slots to hold indices for entries.) Matching at this level
- * implies - the hashes of the lookup name and the record map to the same
- * bucket - the high 32 bits of the hashes (slot bce_hash_msb32s) match. Read
- * cost (on the hash table size, i.e. ignoring reading the name being looked
- * up): - First step normally requires 1 cache line load to pull in the
- * 64-byte htbucket_t with the 7 element slot table holding the hash_msb32s.
- * - In the event (hopefully rare for a hash table with appropriate number of
- * buckets) that more than 7 elements hash to the same bucket, lookup may
- * well need to look not only at the static htbc_elmt_t but at the chain of
- * dynamically allocated htbc_elmt_t's linked to the static htbc_elmt_t,
- * where each of these holds slot entries for additional elements. - Before
- * reaching that point, it is initially required is to read in the hash table
- * record fields (ht_bucket_buf, htnode buf, etc) holding pointers to the
- * arrays, but these cache lines are common to all lookups so will likely
- * already be in the cache. - second step is to match at the record level
- * (htnode/htkb level) once a slot-level match happens. Matching at this
- * level implies the following match - the hash values (the full 64 bits vs.
- * bucket+32 msb, above) With siphash, two names hashing to the same 64-bit
- * value is quite rare. - the name which, on the hash table side, is stored
- * as a list of htkb_t (key buffers). [In some cases, the full name is not
- * compared, and a match is assumed based on hash value match. Read cost: -
- * htnode_t, in one cache line, holds hash value and index for the htkb at
- * the head of the key buffer list - each key buffer (htkb_t) is cache line
- * aligned/sized, and holds 60 bytes of the name and requires a cache line
- * read. Simplification is that a fib lookup requires 3 cache lines: - bucket
- * - htnode - single key buffer (for cases where a name comparision is done)
+ * load in 2 cache lines together.
+ * - first step is to match a record at the bucket/slot level (htab has an
+ * array of htbucket_t/htbc_elmt, where each bucket has 7 slots to hold indices
+ * for entries.) Matching at this level implies
+ * - the hashes of the lookup name and the record map to the same bucket
+ * - the high 32 bits of the hashes (slot bce_hash_msb32s) match. Read
+ * cost (on the hash table size, i.e. ignoring reading the name being
+ * looked up):
+ * - First step normally requires 1 cache line load to pull in the
+ * 64-byte htbucket_t with the 7 element slot table holding the
+ * hash_msb32s.
+ * - In the event (hopefully rare for a hash table with appropriate
+ * number of buckets) that more than 7 elements hash to the same bucket,
+ * lookup may well need to look not only at the static htbc_elmt_t but at
+ * the chain of dynamically allocated htbc_elmt_t's linked to the static
+ * htbc_elmt_t, where each of these holds slot entries for additional elements.
+ * - Before reaching that point, it is initially required to read in the
+ * hash table record fields (ht_bucket_buf, htnode buf, etc) holding
+ * pointers to the arrays, but these cache lines are common to all lookups
+ * so will likely already be in the cache.
+ * - second step is to match at the record level (htnode/htkb level) once a
+ * slot-level match happens. Matching at this level implies the following match
+ * - the hash values (the full 64 bits vs. bucket+32 msb, above).
+ * - the name which, on the hash table side, is stored as a list of htkb_t (key buffers).
*
* Some hashtables (for which rare false positives are tolerable) store hash
* values but no keys. (In ISM NDN forwarder, this was used for dcm_dpf: data
@@ -73,6 +61,15 @@
* are used (or even allocated at hash table creation).
*/
+/* Handy abbreviations for success status, and for boolean values */
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
#define HICN_HASH_INVALID_IDX ~0
/*
* for hicn_hashtb_next_node() iterator, this otherwise illegal context value
diff --git a/hicn-plugin/src/hicn.api b/hicn-plugin/src/hicn.api
index 01e4da213..9643f2098 100644
--- a/hicn-plugin/src/hicn.api
+++ b/hicn-plugin/src/hicn.api
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -16,43 +16,16 @@
option version = "5.1.0";
import "vnet/ip/ip_types.api";
-enum hicn_face_type
+enum hicn_action_type
{
- IP_FACE = 0,
- UDP_FACE,
+ HICN_DISABLE = 0,
+ HICN_ENABLE,
};
-typedef hicn_face_ip
+typedef hicn_face
{
/* IP local address */
- vl_api_address_t local_addr;
-
- /* IP remote address */
- vl_api_address_t remote_addr;
-
- /* IPv4 local port number */
- u32 swif;
-
- /* Face flags */
- u32 flags;
-
- /* Name of the interface */
- u8 if_name[30];
-};
-
-typedef hicn_face_udp
-{
- /* IP local address */
- vl_api_address_t local_addr;
-
- /* IP remote address */
- vl_api_address_t remote_addr;
-
- /* Local port */
- u16 lport;
-
- /* Remote port */
- u16 rport;
+ vl_api_address_t nat_addr;
/* IPv4 local port number */
u32 swif;
@@ -64,12 +37,6 @@ typedef hicn_face_udp
u8 if_name[30];
};
-typedef hicn_face_union
-{
- vl_api_hicn_face_ip_t ip;
- vl_api_hicn_face_udp_t udp;
-};
-
define hicn_api_node_params_set
{
/* Client identifier, set from api_main.my_client_index */
@@ -87,9 +54,6 @@ define hicn_api_node_params_set
/* CS maximum size, otherwise -1 to assign default value */
i32 cs_max_size;
- /* Portion of CS reserved to application, otherwise -1 to assign default value */
- i32 cs_reserved_app;
-
/* Upper bound on PIT entry lifetime, otherwise -1 to assign default value */
f64 pit_max_lifetime_sec;
};
@@ -205,51 +169,6 @@ define hicn_api_node_stats_get_reply
u64 cs_entries_ntw_count;
};
-define hicn_api_face_ip_add
-{
- /* Client identifier, set from api_main.my_client_index */
- u32 client_index;
-
- /* Arbitrary context, so client can match reply to request */
- u32 context;
-
- /* IP local address */
- vl_api_hicn_face_ip_t face;
-};
-
-define hicn_api_face_ip_add_reply
-{
- /* From the request */
- u32 context;
-
- /* Return value: new Face ID, ~0 means no Face was created */
- u32 faceid;
-
- /* Return value, zero means all OK */
- i32 retval;
-};
-
-define hicn_api_face_ip_del
-{
- /* Client identifier, set from api_main.my_client_index */
- u32 client_index;
-
- /* Arbitrary context, so client can match reply to request */
- u32 context;
-
- /* A Face ID to be deleted */
- u32 faceid;
-};
-
-define hicn_api_face_ip_del_reply
-{
- /* From the request */
- u32 context;
-
- /* Return value, zero means all OK */
- i32 retval;
-};
-
define hicn_api_face_stats_details
{
/* From the request */
@@ -291,7 +210,7 @@ define hicn_api_face_stats_dump
u32 context;
};
-define hicn_api_face_ip_params_get
+define hicn_api_face_params_get
{
/* Client identifier, set from api_main.my_client_index */
u32 client_index;
@@ -303,7 +222,7 @@ define hicn_api_face_ip_params_get
u32 faceid;
};
-define hicn_api_face_ip_params_get_reply
+define hicn_api_face_params_get_reply
{
/* From the request */
u32 context;
@@ -315,10 +234,7 @@ define hicn_api_face_ip_params_get_reply
u32 faceid;
/* IP local address */
- vl_api_address_t local_addr;
-
- /* IP remote address */
- vl_api_address_t remote_addr;
+ vl_api_address_t nat_addr;
/* VPP interface (index) associated with the face */
u32 swif;
@@ -327,54 +243,6 @@ define hicn_api_face_ip_params_get_reply
u32 flags;
};
-define hicn_api_face_add
-{
- /* Client identifier, set from api_main.my_client_index */
- u32 client_index;
-
- /* Arbitrary context, so client can match reply to request */
- u32 context;
-
- /* Type of face to add */
- vl_api_hicn_face_type_t type;
-
- /* Face to add */
- vl_api_hicn_face_union_t face;
-};
-
-define hicn_api_face_add_reply
-{
- /* From the request */
- u32 context;
-
- /* Return value: new Face ID, ~0 means no Face was created */
- u32 faceid;
-
- /* Return value, zero means all OK */
- i32 retval;
-};
-
-define hicn_api_face_del
-{
- /* Client identifier, set from api_main.my_client_index */
- u32 client_index;
-
- /* Arbitrary context, so client can match reply to request */
- u32 context;
-
- /* A Face ID to be deleted */
- u32 faceid;
-};
-
-define hicn_api_face_del_reply
-{
- /* From the request */
- u32 context;
-
- /* Return value, zero means all OK */
- i32 retval;
-};
-
define hicn_api_faces_details
{
/* From the request */
@@ -386,11 +254,8 @@ define hicn_api_faces_details
/* Id of the face */
u32 faceid;
- /* Type of face to add */
- vl_api_hicn_face_type_t type;
-
/* Face to add */
- vl_api_hicn_face_union_t face;
+ vl_api_hicn_face_t face;
};
define hicn_api_faces_dump
@@ -425,83 +290,8 @@ define hicn_api_face_get_reply
/* Id of the face */
u32 faceid;
- /* Type of face to add */
- vl_api_hicn_face_type_t type;
-
/* Face to add */
- vl_api_hicn_face_union_t face;
-};
-
-define hicn_api_route_nhops_add
-{
- /* Client identifier, set from api_main.my_client_index */
- u32 client_index;
-
- /* Arbitrary context, so client can match reply to request */
- u32 context;
-
- /* Prefix to be added to the FIB */
- vl_api_prefix_t prefix;
-
- /* A Face ID to the next hop forwarder for the specified prefix */
- u32 face_ids[5];
-
- /* Number of face to add */
- u8 n_faces;
-};
-
-define hicn_api_route_nhops_add_reply
-{
- /* From the request */
- u32 context;
-
- /* Return value, zero means all OK */
- i32 retval;
-};
-
-define hicn_api_route_del
-{
- /* Client identifier, set from api_main.my_client_index */
- u32 client_index;
-
- /* Arbitrary context, so client can match reply to request */
- u32 context;
-
- /* Prefix to be added to the FIB */
- vl_api_prefix_t prefix;
-};
-
-define hicn_api_route_del_reply
-{
- /* From the request */
- u32 context;
-
- /* Return value, zero means all OK */
- i32 retval;
-};
-
-define hicn_api_route_nhop_del
-{
- /* Client identifier, set from api_main.my_client_index */
- u32 client_index;
-
- /* Arbitrary context, so client can match reply to request */
- u32 context;
-
- /* Prefix to be added to the FIB */
- vl_api_prefix_t prefix;
-
- /* Specific next-hop to be removed */
- u32 faceid;
-};
-
-define hicn_api_route_nhop_del_reply
-{
- /* From the request */
- u32 context;
-
- /* Return value, zero means all OK */
- i32 retval;
+ vl_api_hicn_face_t face;
};
define hicn_api_route_get
@@ -624,6 +414,33 @@ define hicn_api_strategy_get_reply
i32 retval;
};
+define hicn_api_enable_disable
+{
+ /* Client identifier, set from api_main.my_client_index */
+ u32 client_index;
+
+ /* Arbitrary context, so client can match reply to request */
+ u32 context;
+
+ /* Enable or disable enable/disable hICN*/
+ vl_api_hicn_action_type_t enable_disable;
+
+ /* Prefix on which we enable/disable hICN*/
+ vl_api_prefix_t prefix;
+};
+
+define hicn_api_enable_disable_reply
+{
+ /* Client identifier, set from api_main.my_client_index */
+ u32 client_index;
+
+ /* Arbitrary context, so client can match reply to request */
+ u32 context;
+
+/* Return value, zero means all OK */
+ i32 retval;
+};
+
define hicn_api_register_prod_app
{
/* Client identifier, set from api_main.my_client_index */
@@ -717,6 +534,42 @@ autoreply define hicn_api_face_cons_del
u32 faceid;
};
+define hicn_api_udp_tunnel_add_del
+{
+ /* Client identifier, set from api_main.my_client_index */
+ u32 client_index;
+
+ /* Arbitrary context, so client can match reply to request */
+ u32 context;
+
+ /* Source address */
+ vl_api_address_t src_addr;
+
+ /* Destination address */
+ vl_api_address_t dst_addr;
+
+ /* Source port */
+ u16 src_port;
+
+ /* Destination port */
+ u16 dst_port;
+
+ /* Add or remove the tunnel*/
+ u8 is_add;
+};
+
+define hicn_api_udp_tunnel_add_del_reply
+{
+ /* From the request */
+ u32 context;
+
+ /* Return value, zero means all OK */
+ i32 retval;
+
+ /* Udp encap index */
+ u32 uei;
+};
+
/*
* fd.io coding-style-patch-verification: ON
*
diff --git a/hicn-plugin/src/hicn.c b/hicn-plugin/src/hicn.c
index 7c2776869..43a717f80 100644
--- a/hicn-plugin/src/hicn.c
+++ b/hicn-plugin/src/hicn.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -16,6 +16,7 @@
#include <vnet/vnet.h>
#include <vnet/plugin/plugin.h>
#include <vlib/vlib.h>
+#include <vnet/interface.h>
#include "hicn.h"
#include "params.h"
@@ -25,7 +26,7 @@
#include "error.h"
#include "faces/app/address_mgr.h"
#include "face_db.h"
-#include "faces/udp/face_udp.h"
+#include "udp_tunnels/udp_tunnel.h"
#include "route.h"
hicn_main_t hicn_main;
@@ -45,8 +46,7 @@ hicn_face_bucket_t *hicn_face_bucket_pool;
* Init hicn forwarder with configurable PIT, CS sizes
*/
static int
-hicn_infra_fwdr_init (uint32_t shard_pit_size, uint32_t shard_cs_size,
- uint32_t cs_reserved)
+hicn_infra_fwdr_init (uint32_t shard_pit_size, uint32_t shard_cs_size)
{
int ret = 0;
@@ -64,12 +64,7 @@ hicn_infra_fwdr_init (uint32_t shard_pit_size, uint32_t shard_cs_size,
hicn_infra_slow_timer = 1;
ret = hicn_pit_create (&hicn_main.pitcs, hicn_infra_pit_size);
- hicn_pit_set_lru_max (&hicn_main.pitcs,
- hicn_infra_cs_size -
- (hicn_infra_cs_size * cs_reserved / 100));
- hicn_pit_set_lru_app_max (&hicn_main.pitcs,
- hicn_infra_cs_size * cs_reserved / 100);
-
+ hicn_pit_set_lru_max (&hicn_main.pitcs, hicn_infra_cs_size);
done:
if ((ret == HICN_ERROR_NONE) && !hicn_infra_fwdr_initialized)
{
@@ -86,12 +81,13 @@ int
hicn_infra_plugin_enable_disable (int enable_disable,
int pit_size_req,
f64 pit_max_lifetime_sec_req,
- int cs_size_req, int cs_reserved_app)
+ int cs_size_req,
+ vnet_link_t link)
{
int ret = 0;
hicn_main_t *sm = &hicn_main;
- uint32_t pit_size, cs_size, cs_reserved;
+ uint32_t pit_size, cs_size;
/* Notice if we're already enabled... */
if (sm->is_enabled)
@@ -168,18 +164,7 @@ hicn_infra_plugin_enable_disable (int enable_disable,
cs_size = (uint32_t) cs_size_req;
}
- if (cs_reserved_app < 0)
- {
- cs_reserved = HICN_PARAM_CS_RESERVED_APP;
- }
- else
- {
- if (cs_reserved_app >= 100)
- ret = HICN_ERROR_CS_CONFIG_RESERVED_OOB;
- cs_reserved = cs_reserved_app;
- }
-
- ret = hicn_infra_fwdr_init (pit_size, cs_size, cs_reserved);
+ ret = hicn_infra_fwdr_init (pit_size, cs_size);
hicn_face_db_init (pit_size);
@@ -188,8 +173,8 @@ hicn_infra_plugin_enable_disable (int enable_disable,
goto done;
}
sm->is_enabled = 1;
-
- hicn_face_udp_init_internal ();
+ sm->link = link;
+ //hicn_face_udp_init_internal ();
done:
@@ -202,7 +187,9 @@ hicn_configure (vlib_main_t * vm, unformat_input_t * input)
u32 pit_size = HICN_PARAM_PIT_ENTRIES_DFLT;
u32 cs_size = HICN_PARAM_CS_ENTRIES_DFLT;
u64 pit_lifetime_max_sec = HICN_PARAM_PIT_LIFETIME_DFLT_MAX_MS / SEC_MS;
- int cs_reserved = HICN_PARAM_CS_RESERVED_APP;
+
+ vnet_link_t link;
+
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
{
@@ -212,19 +199,17 @@ hicn_configure (vlib_main_t * vm, unformat_input_t * input)
;
else if (unformat (input, "pit-lifetime-max %u", &pit_lifetime_max_sec))
;
- else if (unformat (input, "cs-reserved-app %u", &cs_reserved))
- ;
+ else if (unformat (input, "grab mpls-tunnels"))
+ link = VNET_LINK_MPLS;
else
break;
-// clib_error_return (0,
-// "hICN parameter unknown");
}
unformat_free (input);
hicn_infra_plugin_enable_disable (1, pit_size,
pit_lifetime_max_sec,
- cs_size, cs_reserved);
+ cs_size, link);
return 0;
@@ -258,6 +243,8 @@ hicn_init (vlib_main_t * vm)
/* Init the route module */
hicn_route_init ();
+ udp_tunnel_init ();
+
return error;
}
diff --git a/hicn-plugin/src/hicn.h b/hicn-plugin/src/hicn.h
index b469a7ed9..3d980bd49 100644
--- a/hicn-plugin/src/hicn.h
+++ b/hicn-plugin/src/hicn.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -30,6 +30,8 @@
#undef ip_prefix_len
#define ip_prefix_len(_a) (_a)->len
+#include "faces/face.h"
+
#include <netinet/in.h>
#include <vnet/ip/ip.h>
#include <vnet/tcp/tcp_packet.h>
@@ -37,6 +39,10 @@
#include <vnet/ip/ip4_packet.h>
#include <vnet/buffer.h>
+/**
+ * @file
+ */
+
/* Helper for avoiding warnings about type-punning */
#define UNION_CAST(x, destType) \
(((union {__typeof__(x) a; destType b;})x).b)
@@ -54,11 +60,11 @@ typedef u8 weight_t;
#define VLIB_BUFFER_MIN_CHAIN_SEG_SIZE (128)
#endif
-#define HICN_BUFFER_FLAGS_DEFAULT 0x00
-#define HICN_BUFFER_FLAGS_FACE_IS_APP 0x01
/* 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_UDP4_TUNNEL 0x04
+#define HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL 0x08
/* The following is stored in the opaque2 field in the vlib_buffer_t */
typedef struct
@@ -76,8 +82,7 @@ typedef struct
u8 dpo_ctx_id; /* used for data path */
u8 vft_id; /* " */
- dpo_id_t face_dpo_id; /* ingress iface, sizeof(dpo_id_t)
- * <= sizeof(u64) */
+ hicn_face_id_t face_id; /* ingress iface, sizeof(u32) */
u32 in_faces_vec_id; /* vector of possible input face for a data packet */
hicn_type_t type;
diff --git a/hicn-plugin/src/hicn_api.c b/hicn-plugin/src/hicn_api.c
index 7a6babeb2..e6050f96c 100644
--- a/hicn-plugin/src/hicn_api.c
+++ b/hicn-plugin/src/hicn_api.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -25,8 +25,8 @@
#include <vnet/ip/ip_types_api.h>
#include <vnet/ip/ip_format_fns.h>
-#include "faces/ip/face_ip.h"
-#include "faces/udp/face_udp.h"
+#include "faces/face.h"
+#include "udp_tunnels/udp_tunnel.h"
#include "infra.h"
#include "parser.h"
#include "mgmt.h"
@@ -59,7 +59,7 @@
*/
always_inline vnet_api_error_t
hicn_face_api_entry_params_serialize (hicn_face_id_t faceid,
- vl_api_hicn_api_face_ip_params_get_reply_t
+ vl_api_hicn_api_face_params_get_reply_t
* reply);
@@ -88,14 +88,11 @@ vl_api_hicn_api_node_params_set_t_handler (vl_api_hicn_api_node_params_set_t *
int cs_max_size = clib_net_to_host_i32 (mp->cs_max_size);
cs_max_size = cs_max_size == -1 ? HICN_PARAM_CS_ENTRIES_DFLT : cs_max_size;
- int cs_reserved_app = clib_net_to_host_i32 (mp->cs_reserved_app);
- cs_reserved_app = cs_reserved_app >= 0
- && cs_reserved_app < 100 ? cs_reserved_app : HICN_PARAM_CS_RESERVED_APP;
-
rv = hicn_infra_plugin_enable_disable ((int) (mp->enable_disable),
pit_max_size,
pit_max_lifetime_sec,
- cs_max_size, cs_reserved_app);
+ cs_max_size,
+ ~0);
REPLY_MACRO (VL_API_HICN_API_NODE_PARAMS_SET_REPLY /* , rmp, mp, rv */ );
}
@@ -141,119 +138,11 @@ vl_api_hicn_api_node_stats_get_t_handler (vl_api_hicn_api_node_stats_get_t *
}
-/****** FACE *******/
-static hicn_error_t
-hicn_api_face_ip_add (vl_api_hicn_face_ip_t * mp, hicn_face_id_t * face_id)
-{
- hicn_error_t rv = HICN_ERROR_NONE;
-
- vnet_main_t *vnm = vnet_get_main ();
-
- ip46_address_t local_addr;
- ip46_address_t remote_addr;
- ip_address_decode (&mp->local_addr, &local_addr);
- ip_address_decode (&mp->remote_addr, &remote_addr);
-
- u32 sw_if = clib_net_to_host_u32 (mp->swif);
-
- if (ip46_address_is_zero (&local_addr))
- {
- if (!vnet_sw_interface_is_valid (vnm, sw_if))
- {
- rv = HICN_ERROR_UNSPECIFIED;
- }
-
- if ((rv == HICN_ERROR_NONE) && ip46_address_is_ip4 (&remote_addr))
- {
- ip_interface_address_t *interface_address;
- ip4_address_t *addr =
- ip4_interface_address_matching_destination (&ip4_main,
- &remote_addr.ip4,
- sw_if,
- &interface_address);
- if (addr == NULL)
- addr = ip4_interface_first_address (&ip4_main,
- sw_if, &interface_address);
-
- if (addr == NULL)
- rv = HICN_ERROR_UNSPECIFIED;
- else
- ip46_address_set_ip4 (&local_addr, addr);
- }
- else
- {
- ip_interface_address_t *interface_address;
- ip6_interface_address_matching_destination (&ip6_main,
- &remote_addr.ip6, sw_if,
- &interface_address);
- ip6_address_t *addr = NULL;
- if (rv == HICN_ERROR_NONE && interface_address != NULL)
- {
- addr =
- (ip6_address_t *)
- ip_interface_address_get_address (&ip6_main.lookup_main,
- interface_address);
- }
- else
- {
- addr = ip6_interface_first_address (&ip6_main, sw_if);
- }
-
- if (addr == NULL)
- rv = HICN_ERROR_UNSPECIFIED;
- else
- ip46_address_set_ip6 (&local_addr, addr);
- }
- }
-
- if (rv == HICN_ERROR_NONE)
- rv = hicn_face_ip_add (&local_addr, &remote_addr, sw_if, face_id, 0);
-
- return rv;
-}
-
-static void
-vl_api_hicn_api_face_ip_add_t_handler (vl_api_hicn_api_face_ip_add_t * mp)
-{
- vl_api_hicn_api_face_ip_add_reply_t *rmp;
- hicn_error_t rv = HICN_ERROR_NONE;
-
- hicn_main_t *sm = &hicn_main;
- hicn_face_id_t face_id = HICN_FACE_NULL;
- rv = hicn_api_face_ip_add (&(mp->face), &face_id);
-
- /* *INDENT-OFF* */
- REPLY_MACRO2 (VL_API_HICN_API_FACE_IP_ADD_REPLY /* , rmp, mp, rv */ ,(
- {
- rmp->faceid = clib_host_to_net_u32 ((u32) face_id);
- rmp->retval = rv;
- }));
- /* *INDENT-ON* */
-}
-
-static void
-vl_api_hicn_api_face_ip_del_t_handler (vl_api_hicn_api_face_ip_del_t * mp)
-{
- vl_api_hicn_api_face_ip_del_reply_t *rmp;
- int rv = HICN_ERROR_FACE_NOT_FOUND;
-
- hicn_main_t *sm = &hicn_main;
-
- hicn_face_id_t faceid = clib_net_to_host_u32 (mp->faceid);
- if (hicn_dpoi_idx_is_valid (faceid))
- {
- rv = hicn_face_ip_del (faceid);
- }
-
- REPLY_MACRO (VL_API_HICN_API_FACE_IP_DEL_REPLY /* , rmp, mp, rv */ );
-
-}
-
static void
- vl_api_hicn_api_face_ip_params_get_t_handler
- (vl_api_hicn_api_face_ip_params_get_t * mp)
+ vl_api_hicn_api_face_params_get_t_handler
+ (vl_api_hicn_api_face_params_get_t * mp)
{
- vl_api_hicn_api_face_ip_params_get_reply_t *rmp;
+ vl_api_hicn_api_face_params_get_reply_t *rmp;
int rv = 0;
hicn_main_t *sm = &hicn_main;
@@ -261,7 +150,7 @@ static void
hicn_face_id_t faceid = clib_net_to_host_u32 (mp->faceid);
/* *INDENT-OFF* */
- REPLY_MACRO2 (VL_API_HICN_API_FACE_IP_PARAMS_GET_REPLY, (
+ REPLY_MACRO2 (VL_API_HICN_API_FACE_PARAMS_GET_REPLY, (
{
rv = hicn_face_api_entry_params_serialize(faceid, rmp);
rmp->retval = clib_host_to_net_u32(rv);
@@ -269,149 +158,16 @@ static void
/* *INDENT-ON* */
}
-static hicn_error_t
-hicn_api_face_udp_add (vl_api_hicn_face_udp_t * mp, hicn_face_id_t * face_id)
-{
- hicn_error_t rv = HICN_ERROR_NONE;
-
- ip46_address_t local_addr = ip46_address_initializer;
- ip46_address_t remote_addr = ip46_address_initializer;
- u16 lport;
- u16 rport;
- u32 sw_if;
- ip_address_decode (&mp->local_addr, &local_addr);
- ip_address_decode (&mp->remote_addr, &remote_addr);
- //Do not byteswap. We store ports in network order
- lport = mp->lport;
- rport = mp->rport;
- sw_if = clib_net_to_host_u32 (mp->swif);
-
- int input_is_ok = !ip46_address_is_zero (&local_addr)
- && !ip46_address_is_zero (&remote_addr)
- &&
- ((ip46_address_is_ip4 (&local_addr) && ip46_address_is_ip4 (&remote_addr))
- || (!ip46_address_is_ip4 (&local_addr)
- && !ip46_address_is_ip4 (&remote_addr))) && lport != 0 && rport != 0;
-
- if (!input_is_ok)
- {
- rv = HICN_ERROR_UNSPECIFIED;
- }
- else
- {
- rv = hicn_face_udp_add (&local_addr,
- &remote_addr, lport, rport, sw_if, face_id);
- }
- return rv;
-}
-
-static void
-vl_api_hicn_api_face_add_t_handler (vl_api_hicn_api_face_add_t * mp)
-{
- vl_api_hicn_api_face_add_reply_t *rmp;
- hicn_error_t rv = HICN_ERROR_NONE;
-
- hicn_main_t *sm = &hicn_main;
- hicn_face_id_t face_id;
- vl_api_hicn_face_type_t face_type = clib_net_to_host_u32 (mp->type);
-
- switch (face_type)
- {
- case IP_FACE:
- rv = hicn_api_face_ip_add (&(mp->face.ip), &face_id);
- break;
- case UDP_FACE:
- rv = hicn_api_face_udp_add (&(mp->face.udp), &face_id);
- break;
- default:
- rv = HICN_ERROR_UNSPECIFIED;
- break;
- }
-
- /* *INDENT-OFF* */
- REPLY_MACRO2 (VL_API_HICN_API_FACE_ADD_REPLY /* , rmp, mp, rv */ ,(
- {
- rmp->faceid = clib_host_to_net_u32 ((u32) face_id);
- rmp->retval = clib_host_to_net_u32 (rv);
- }));
- /* *INDENT-ON* */
-}
-
static void
-vl_api_hicn_api_face_del_t_handler (vl_api_hicn_api_face_del_t * mp)
-{
- vl_api_hicn_api_face_del_reply_t *rmp;
- int rv = HICN_ERROR_FACE_NOT_FOUND;
-
- hicn_main_t *sm = &hicn_main;
-
- hicn_face_id_t faceid = clib_net_to_host_u32 (mp->faceid);
- if (hicn_dpoi_idx_is_valid (faceid))
- {
- hicn_face_t *face = hicn_dpoi_get_from_idx (faceid);
- hicn_face_vft_t *vft = hicn_face_get_vft (face->shared.face_type);
- rv = vft->hicn_face_del (faceid);
- }
-
- REPLY_MACRO (VL_API_HICN_API_FACE_DEL_REPLY /* , rmp, mp, rv */ );
-}
-
-static void
-send_face_ip_details (hicn_face_t * face, vl_api_hicn_face_ip_t * mp)
+send_face_details (hicn_face_t * face, vl_api_hicn_face_t * mp)
{
vnet_main_t *vnm = vnet_get_main ();
- hicn_face_ip_t *face_ip = (hicn_face_ip_t *) face->data;
- ip_address_encode (&face_ip->local_addr, IP46_TYPE_ANY, &mp->local_addr);
- ip_address_encode (&face_ip->remote_addr, IP46_TYPE_ANY, &mp->remote_addr);
- mp->flags = clib_host_to_net_u32 (face->shared.flags);
- mp->swif = clib_net_to_host_u32 (face->shared.sw_if);
+ ip_address_encode (&face->nat_addr, IP46_TYPE_ANY, &mp->nat_addr);
+ mp->flags = clib_host_to_net_u32 (face->flags);
+ mp->swif = clib_net_to_host_u32 (face->sw_if);
vnet_sw_interface_t *sw_interface =
- vnet_get_sw_interface_or_null (vnm, face->shared.sw_if);
- u8 *sbuf = 0;
- if (sw_interface != NULL)
- {
- sbuf =
- format (0, "%U", format_vnet_sw_interface_name, vnm, sw_interface);
- strcpy ((char *) (mp->if_name), (char *) sbuf);
- }
-}
-
-static void
-send_face_udp_details (hicn_face_t * face, vl_api_hicn_face_udp_t * mp)
-{
- vnet_main_t *vnm = vnet_get_main ();
- hicn_face_udp_t *face_udp = (hicn_face_udp_t *) face->data;
- if (face_udp->hdrs.ip4.ip.ip_version_and_header_length == 0x45)
- {
- ip46_address_t src_addr = { 0 };
- ip46_address_t dst_addr = { 0 };
- ip46_address_set_ip4 (&src_addr, &(face_udp->hdrs.ip4.ip.src_address));
- ip46_address_set_ip4 (&dst_addr, &(face_udp->hdrs.ip4.ip.dst_address));
-
- ip_address_encode (&src_addr, IP46_TYPE_ANY, &(mp->local_addr));
- ip_address_encode (&dst_addr, IP46_TYPE_ANY, &(mp->remote_addr));
- //Do not swap, they are already in network order
- mp->lport = face_udp->hdrs.ip4.udp.src_port;
- mp->rport = face_udp->hdrs.ip4.udp.dst_port;
- }
- else
- {
- ip46_address_t src_addr = { 0 };
- ip46_address_t dst_addr = { 0 };
- ip46_address_set_ip6 (&src_addr, &(face_udp->hdrs.ip6.ip.src_address));
- ip46_address_set_ip6 (&dst_addr, &(face_udp->hdrs.ip6.ip.dst_address));
-
- ip_address_encode (&src_addr, IP46_TYPE_ANY, &(mp->local_addr));
- ip_address_encode (&dst_addr, IP46_TYPE_ANY, &(mp->remote_addr));
- //Do not swap, they are already in network order
- mp->lport = face_udp->hdrs.ip6.udp.src_port;
- mp->rport = face_udp->hdrs.ip6.udp.dst_port;
- }
- mp->flags = clib_host_to_net_u32 (face->shared.flags);
- mp->swif = clib_net_to_host_u32 (face->shared.sw_if);
- vnet_sw_interface_t *sw_interface =
- vnet_get_sw_interface_or_null (vnm, face->shared.sw_if);
+ vnet_get_sw_interface_or_null (vnm, face->sw_if);
u8 *sbuf = 0;
if (sw_interface != NULL)
{
@@ -433,17 +189,7 @@ send_faces_details (vl_api_registration_t * reg,
mp->_vl_msg_id = htons (VL_API_HICN_API_FACES_DETAILS + hm->msg_id_base);
mp->context = context;
- if (face->shared.face_type == hicn_face_ip_type)
- {
- mp->type = clib_host_to_net_u32 (IP_FACE);
- send_face_ip_details (face, &(mp->face.ip));
- }
- else if (face->shared.face_type == hicn_face_udp_type)
- {
- mp->type = clib_host_to_net_u32 (UDP_FACE);
- send_face_udp_details (face, &(mp->face.udp));
- }
-
+ send_face_details (face, &(mp->face));
vl_api_send_msg (reg, (u8 *) mp);
}
@@ -483,16 +229,7 @@ vl_api_hicn_api_face_get_t_handler (vl_api_hicn_api_face_get_t * mp)
if (rv)
{
hicn_face_t * face = hicn_dpoi_get_from_idx(faceid);
- if (face->shared.face_type == hicn_face_ip_type)
- {
- rmp->type = IP_FACE;
- send_face_ip_details(face, &(rmp->face.ip));
- }
- else if (face->shared.face_type == hicn_face_udp_type)
- {
- rmp->type = UDP_FACE;
- send_face_udp_details(face, &(rmp->face.udp));
- }
+ send_face_details(face, &(rmp->face));
rv = HICN_ERROR_NONE;
}
else
@@ -568,77 +305,6 @@ static void
/****** ROUTE *******/
-static void
-vl_api_hicn_api_route_nhops_add_t_handler (vl_api_hicn_api_route_nhops_add_t
- * mp)
-{
- vl_api_hicn_api_route_nhops_add_reply_t *rmp;
- int rv = HICN_ERROR_NONE;
- hicn_face_id_t face_ids[HICN_PARAM_FIB_ENTRY_NHOPS_MAX];
-
- hicn_main_t *sm = &hicn_main;
-
- fib_prefix_t prefix;
- ip_prefix_decode (&mp->prefix, &prefix);
-
- u8 n_faces = mp->n_faces;
-
- for (int i = 0; i < HICN_PARAM_FIB_ENTRY_NHOPS_MAX; i++)
- {
- face_ids[i] = clib_net_to_host_u32 (mp->face_ids[i]);
- }
-
- if ((face_ids == NULL) || (n_faces > HICN_PARAM_FIB_ENTRY_NHOPS_MAX))
- {
- rv = VNET_API_ERROR_INVALID_ARGUMENT;
- }
- if (rv == HICN_ERROR_NONE)
- {
- rv = hicn_route_add (face_ids, n_faces, &prefix);
-
- if (rv == HICN_ERROR_ROUTE_ALREADY_EXISTS)
- {
- rv = hicn_route_add_nhops (face_ids, n_faces, &prefix);
- }
- }
- REPLY_MACRO (VL_API_HICN_API_ROUTE_NHOPS_ADD_REPLY /* , rmp, mp, rv */ );
-}
-
-
-static void vl_api_hicn_api_route_del_t_handler
- (vl_api_hicn_api_route_del_t * mp)
-{
- vl_api_hicn_api_route_del_reply_t *rmp;
- int rv = HICN_ERROR_NONE;
-
- hicn_main_t *sm = &hicn_main;
-
- fib_prefix_t prefix;
- ip_prefix_decode (&mp->prefix, &prefix);
-
- rv = hicn_route_del (&prefix);
-
- REPLY_MACRO (VL_API_HICN_API_ROUTE_DEL_REPLY /* , rmp, mp, rv */ );
-}
-
-static void vl_api_hicn_api_route_nhop_del_t_handler
- (vl_api_hicn_api_route_nhop_del_t * mp)
-{
- vl_api_hicn_api_route_nhop_del_reply_t *rmp;
- int rv = HICN_ERROR_NONE;
-
- hicn_main_t *sm = &hicn_main;
-
- fib_prefix_t prefix;
- ip_prefix_decode (&mp->prefix, &prefix);
- hicn_face_id_t faceid = clib_net_to_host_u32 (mp->faceid);
-
-
- rv = hicn_route_del_nhop (&prefix, faceid);
-
- REPLY_MACRO (VL_API_HICN_API_ROUTE_NHOP_DEL_REPLY /* , rmp, mp, rv */ );
-}
-
static void vl_api_hicn_api_route_get_t_handler
(vl_api_hicn_api_route_get_t * mp)
{
@@ -663,9 +329,7 @@ static void vl_api_hicn_api_route_get_t_handler
hicn_dpo_ctx = hicn_strategy_dpo_ctx_get(hicn_dpo_id->dpoi_index);
for (int i = 0; hicn_dpo_ctx != NULL && i < hicn_dpo_ctx->entry_count; i++)
{
- if (dpo_id_is_valid(&hicn_dpo_ctx->next_hops[i]))
- {
- rmp->faceids[i] =((dpo_id_t *) &hicn_dpo_ctx->next_hops[i])->dpoi_index;}
+ rmp->faceids[i] = hicn_dpo_ctx->next_hops[i];
}
rmp->strategy_id = clib_host_to_net_u32(hicn_dpo_get_vft_id(hicn_dpo_id));}
}));
@@ -699,14 +363,10 @@ send_route_details (vl_api_registration_t * reg,
for (int i = 0; hicn_dpo_ctx != NULL && i < hicn_dpo_ctx->entry_count;
i++)
{
- if (dpo_id_is_valid (&hicn_dpo_ctx->next_hops[i]))
- {
- mp->faceids[i] =
- clib_host_to_net_u32 (((dpo_id_t *) &
- hicn_dpo_ctx->
- next_hops[i])->dpoi_index);
+ mp->faceids[i] =
+ clib_host_to_net_u32 (hicn_dpo_ctx->
+ next_hops[i]);
mp->nfaces++;
- }
}
mp->strategy_id =
clib_host_to_net_u32 (hicn_dpo_get_vft_id (hicn_dpo_id));
@@ -930,6 +590,83 @@ vl_api_hicn_api_face_cons_del_t_handler (vl_api_hicn_api_face_cons_del_t * mp)
REPLY_MACRO (VL_API_HICN_API_FACE_CONS_DEL_REPLY /* , rmp, mp, rv */ );
}
+static void vl_api_hicn_api_enable_disable_t_handler
+(vl_api_hicn_api_enable_disable_t * mp)
+{
+ vl_api_hicn_api_enable_disable_reply_t *rmp;
+ int rv = HICN_ERROR_NONE;
+
+ hicn_main_t *sm = &hicn_main;
+
+ fib_prefix_t prefix;
+ ip_prefix_decode (&mp->prefix, &prefix);
+
+ switch (clib_net_to_host_u32(mp->enable_disable))
+ {
+ case HICN_ENABLE:
+ rv = hicn_route_enable(&prefix);
+ break;
+ case HICN_DISABLE:
+ rv = hicn_route_disable(&prefix);
+ break;
+ }
+
+ REPLY_MACRO (VL_API_HICN_API_ENABLE_DISABLE_REPLY/* , rmp, mp, rv */ );
+}
+
+/*********************************** UDP TUNNELS ************************************/
+
+static void vl_api_hicn_api_udp_tunnel_add_del_t_handler
+(vl_api_hicn_api_udp_tunnel_add_del_t * mp)
+{
+ vl_api_hicn_api_udp_tunnel_add_del_reply_t *rmp;
+ int rv = HICN_ERROR_NONE;
+
+ hicn_main_t *sm = &hicn_main;
+
+ ip46_address_t src_addr;
+ ip46_address_t dst_addr;
+ u16 src_port;
+ u16 dst_port;
+ index_t uei = ~0;
+
+ ip46_type_t type = ip_address_decode (&mp->src_addr, &src_addr);
+ if (type != ip_address_decode (&mp->dst_addr, &dst_addr))
+ {
+ rv = HICN_ERROR_UDP_TUNNEL_SRC_DST_TYPE;
+ goto done;
+ }
+
+ src_port = clib_net_to_host_u16(mp->src_port);
+ dst_port = clib_net_to_host_u16(mp->dst_port);
+
+ fib_protocol_t proto = ip46_address_is_ip4(&src_addr) ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6;
+
+ index_t fib_index = fib_table_find (proto, HICN_FIB_TABLE);
+
+ if (mp->is_add)
+ {
+ uei = udp_tunnel_add(proto,
+ fib_index, &src_addr, &dst_addr, src_port, dst_port,
+ UDP_ENCAP_FIXUP_NONE);
+ }
+ else
+ {
+ udp_tunnel_del(proto,
+ fib_index, &src_addr, &dst_addr, src_port, dst_port,
+ UDP_ENCAP_FIXUP_NONE);
+ }
+
+
+ done:
+
+ /* *INDENT-OFF* */
+ REPLY_MACRO2 (VL_API_HICN_API_UDP_TUNNEL_ADD_DEL_REPLY, (
+ {
+ rmp->uei = clib_host_to_net_u32(uei);
+ }));
+ /* *INDENT-ON* */
+}
/************************************************************************************/
@@ -955,7 +692,7 @@ hicn_api_plugin_hookup (vlib_main_t * vm)
*/
vnet_api_error_t
hicn_face_api_entry_params_serialize (hicn_face_id_t faceid,
- vl_api_hicn_api_face_ip_params_get_reply_t
+ vl_api_hicn_api_face_params_get_reply_t
* reply)
{
int rv = HICN_ERROR_NONE;
@@ -967,15 +704,13 @@ hicn_face_api_entry_params_serialize (hicn_face_id_t faceid,
}
hicn_face_t *face = hicn_dpoi_get_from_idx (faceid);
- if (face != NULL && face->shared.face_type == hicn_face_ip_type)
+ if (face != NULL)
{
- hicn_face_ip_t *face_ip = (hicn_face_ip_t *) face->data;
- ip_address_encode (&face_ip->local_addr, IP46_TYPE_ANY,
- &reply->local_addr);
- ip_address_encode (&face_ip->remote_addr, IP46_TYPE_ANY,
- &reply->remote_addr);
- reply->swif = clib_host_to_net_u32 (face->shared.sw_if);
- reply->flags = clib_host_to_net_u32 (face->shared.flags);
+ ip_address_encode (&face->nat_addr, IP46_TYPE_ANY,
+ &reply->nat_addr);
+
+ reply->swif = clib_host_to_net_u32 (face->sw_if);
+ reply->flags = clib_host_to_net_u32 (face->flags);
reply->faceid = clib_host_to_net_u32 (faceid);
}
else
diff --git a/hicn-plugin/src/hicn_api.h b/hicn-plugin/src/hicn_api.h
index 79b561be4..ec10a6bbd 100644
--- a/hicn-plugin/src/hicn_api.h
+++ b/hicn-plugin/src/hicn_api.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -16,7 +16,13 @@
#ifndef __HICN_API_H__
#define __HICN_API_H__
+/**
+ * @file
+ */
+
+
#define HICN_STRATEGY_NULL ~0
+#define HICN_FIB_TABLE 10
/* define message structures */
#define vl_typedefs
diff --git a/hicn-plugin/src/hicn_api_test.c b/hicn-plugin/src/hicn_api_test.c
index 08a579914..e4704e8ea 100644
--- a/hicn-plugin/src/hicn_api_test.c
+++ b/hicn-plugin/src/hicn_api_test.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -222,11 +222,7 @@ hicn_test_main_t hicn_test_main;
#define foreach_standard_reply_retval_handler \
_(hicn_api_node_params_set_reply) \
-_(hicn_api_face_ip_del_reply) \
-_(hicn_api_face_del_reply) \
-_(hicn_api_route_nhops_add_reply) \
-_(hicn_api_route_del_reply) \
-_(hicn_api_route_nhop_del_reply)
+_(hicn_api_enable_disable_reply)
#define _(n) \
static void vl_api_##n##_t_handler \
@@ -253,26 +249,16 @@ foreach_standard_reply_retval_handler;
_(HICN_API_NODE_PARAMS_SET_REPLY, hicn_api_node_params_set_reply) \
_(HICN_API_NODE_PARAMS_GET_REPLY, hicn_api_node_params_get_reply) \
_(HICN_API_NODE_STATS_GET_REPLY, hicn_api_node_stats_get_reply) \
-_(HICN_API_FACE_IP_DEL_REPLY, hicn_api_face_ip_del_reply) \
-_(HICN_API_FACE_IP_ADD_REPLY, hicn_api_face_ip_add_reply) \
-_(HICN_API_FACE_ADD_REPLY, hicn_api_face_add_reply) \
-_(HICN_API_FACE_DEL_REPLY, hicn_api_face_del_reply) \
_(HICN_API_FACE_GET_REPLY, hicn_api_face_get_reply) \
_(HICN_API_FACES_DETAILS, hicn_api_faces_details) \
_(HICN_API_FACE_STATS_DETAILS, hicn_api_face_stats_details) \
-_(HICN_API_ROUTE_NHOPS_ADD_REPLY, hicn_api_route_nhops_add_reply) \
-_(HICN_API_FACE_IP_PARAMS_GET_REPLY, hicn_api_face_ip_params_get_reply) \
+_(HICN_API_FACE_PARAMS_GET_REPLY, hicn_api_face_params_get_reply) \
_(HICN_API_ROUTE_GET_REPLY, hicn_api_route_get_reply) \
_(HICN_API_ROUTES_DETAILS, hicn_api_routes_details) \
-_(HICN_API_ROUTE_DEL_REPLY, hicn_api_route_del_reply) \
-_(HICN_API_ROUTE_NHOP_DEL_REPLY, hicn_api_route_nhop_del_reply) \
_(HICN_API_STRATEGIES_GET_REPLY, hicn_api_strategies_get_reply) \
_(HICN_API_STRATEGY_GET_REPLY, hicn_api_strategy_get_reply) \
-_(HICN_API_REGISTER_PROD_APP_REPLY, hicn_api_register_prod_app_reply) \
-_(HICN_API_FACE_PROD_DEL_REPLY, hicn_api_face_prod_del_reply) \
-_(HICN_API_REGISTER_CONS_APP_REPLY, hicn_api_register_cons_app_reply) \
-_(HICN_API_FACE_CONS_DEL_REPLY, hicn_api_face_cons_del_reply)
-
+_(HICN_API_ENABLE_DISABLE_REPLY, hicn_api_enable_disable_reply) \
+_(HICN_API_UDP_TUNNEL_ADD_DEL_REPLY, hicn_api_udp_tunnel_add_del_reply)
static int
api_hicn_api_node_params_set (vat_main_t * vam)
@@ -309,7 +295,7 @@ api_hicn_api_node_params_set (vat_main_t * vam)
/* Construct the API message */
M (HICN_API_NODE_PARAMS_SET, mp);
- mp->enable_disable = enable_disable;
+ mp->enable_disable = clib_host_to_net_u32(enable_disable);
mp->pit_max_size = clib_host_to_net_i32 (pit_size);
mp->cs_max_size = clib_host_to_net_i32 (cs_size);
mp->pit_max_lifetime_sec = pit_max_lifetime_sec;
@@ -451,263 +437,10 @@ static void
}
static int
-api_hicn_api_face_ip_add (vat_main_t * vam)
+api_hicn_api_face_params_get (vat_main_t * vam)
{
unformat_input_t *input = vam->input;
- ip46_address_t local_addr = { 0 };
- ip46_address_t remote_addr = { 0 };
- int ret = HICN_ERROR_NONE;
- int sw_if = 0;
- vl_api_hicn_api_face_add_t *mp;
-
- /* Parse args required to build the message */
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat
- (input, "local %U", unformat_ip46_address, &local_addr,
- IP46_TYPE_ANY));
- else
- if (unformat
- (input, "remote %U", unformat_ip46_address, &remote_addr,
- IP46_TYPE_ANY));
- else if (unformat (input, "intfc %d", &sw_if));
- else
- {
- break;
- }
- }
-
- /* Check for presence of both addresses */
- if (ip46_address_is_zero (&remote_addr))
- {
- clib_warning ("Incomplete IP face. Please specify remote address");
- return (1);
- }
- /* Construct the API message */
- M (HICN_API_FACE_ADD, mp);
- mp->type = clib_host_to_net_u32 (IP_FACE);
- ip_address_encode (&local_addr, IP46_TYPE_ANY, &mp->face.ip.local_addr);
- ip_address_encode (&remote_addr, IP46_TYPE_ANY, &mp->face.ip.remote_addr);
- mp->face.ip.swif = clib_host_to_net_u32 (sw_if);
-
- /* send it... */
- S (mp);
-
- /* Wait for a reply... */
- W (ret);
-
- return ret;
-}
-
-static void
- vl_api_hicn_api_face_ip_add_reply_t_handler
- (vl_api_hicn_api_face_ip_add_reply_t * rmp)
-{
- vat_main_t *vam = hicn_test_main.vat_main;
- i32 retval = ntohl (rmp->retval);
-
- if (vam->async_mode)
- {
- vam->async_errors += (retval < 0);
- return;
- }
- vam->retval = retval;
- vam->result_ready = 1;
-
- if (vam->retval < 0)
- {
- //vpp_api_test infra will also print out string form of error
- fformat (vam->ofp, " (API call error: %d)\n", vam->retval);
- return;
- }
- fformat (vam->ofp, "New Face ID: %d\n", ntohl (rmp->faceid));
-}
-
-static int
-api_hicn_api_face_udp_add (vat_main_t * vam)
-{
- unformat_input_t *input = vam->input;
- ip46_address_t local_addr = ip46_address_initializer;
- ip46_address_t remote_addr = ip46_address_initializer;
- u32 sport = 0;
- u32 dport = 0;
- int ret = HICN_ERROR_NONE;
- int sw_if = ~0;
- vl_api_hicn_api_face_add_t *mp;
-
- /* Parse args required to build the message */
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat
- (input, "local %U port %u", unformat_ip46_address, &local_addr,
- IP46_TYPE_ANY, &sport));
- else
- if (unformat
- (input, "remote %U port %u", unformat_ip46_address, &remote_addr,
- IP46_TYPE_ANY, &dport));
- else if (unformat (input, "intfc %d", &sw_if));
- else
- {
- break;
- }
- }
-
- /* Check for presence of both addresses */
- if (ip46_address_is_zero (&remote_addr)
- || ip46_address_is_zero (&local_addr) || sport == 0 || dport == 0)
- {
- clib_warning
- ("Incomplete UDP face. Please specify local and remote address and port");
- return (1);
- }
- /* Construct the API message */
- M (HICN_API_FACE_ADD, mp);
- mp->type = clib_host_to_net_u32 (UDP_FACE);
- ip_address_encode (&local_addr, IP46_TYPE_ANY, &mp->face.udp.local_addr);
- ip_address_encode (&remote_addr, IP46_TYPE_ANY, &mp->face.udp.remote_addr);
- mp->face.udp.lport = clib_host_to_net_u16 (sport);
- mp->face.udp.rport = clib_host_to_net_u16 (dport);
- mp->face.udp.swif = clib_host_to_net_u32 (sw_if);
-
- /* send it... */
- S (mp);
-
- /* Wait for a reply... */
- W (ret);
-
- return ret;
-}
-
-static int
-api_hicn_api_face_add (vat_main_t * vam)
-{
- unformat_input_t *input = vam->input;
- int ret = HICN_ERROR_NONE;
- u32 type = ~0;
-
- /* Parse args required to build the message */
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (input, "type %d", &type));
- else
- {
- break;
- }
- }
-
- vam->input = input;
-
- if (type == IP_FACE)
- ret = api_hicn_api_face_ip_add (vam);
- else if (type == UDP_FACE)
- ret = api_hicn_api_face_udp_add (vam);
-
- return ret;
-}
-
-static void
- vl_api_hicn_api_face_add_reply_t_handler
- (vl_api_hicn_api_face_add_reply_t * rmp)
-{
- vat_main_t *vam = hicn_test_main.vat_main;
- i32 retval = ntohl (rmp->retval);
-
- if (vam->async_mode)
- {
- vam->async_errors += (retval < 0);
- return;
- }
- vam->retval = retval;
- vam->result_ready = 1;
-
- if (vam->retval < 0)
- {
- //vpp_api_test infra will also print out string form of error
- fformat (vam->ofp, " (API call error: %d)\n", vam->retval);
- return;
- }
- fformat (vam->ofp, "New Face ID: %d\n", ntohl (rmp->faceid));
-}
-
-static int
-api_hicn_api_face_ip_del (vat_main_t * vam)
-{
- unformat_input_t *input = vam->input;
- vl_api_hicn_api_face_ip_del_t *mp;
- u32 faceid = 0, ret;
-
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (input, "face %d", &faceid))
- {;
- }
- else
- {
- break;
- }
- }
-
- //Check for presence of face ID
- if (faceid == ~0)
- {
- clib_warning ("Please specify face ID");
- return 1;
- }
- //Construct the API message
- M (HICN_API_FACE_IP_DEL, mp);
- mp->faceid = clib_host_to_net_u32 (faceid);
-
- //send it...
- S (mp);
-
- //Wait for a reply...
- W (ret);
-
- return ret;
-}
-
-static int
-api_hicn_api_face_del (vat_main_t * vam)
-{
- unformat_input_t *input = vam->input;
- vl_api_hicn_api_face_del_t *mp;
- u32 faceid = 0, ret;
-
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (input, "face %d", &faceid))
- {;
- }
- else
- {
- break;
- }
- }
-
- //Check for presence of face ID
- if (faceid == ~0)
- {
- clib_warning ("Please specify face ID");
- return 1;
- }
- //Construct the API message
- M (HICN_API_FACE_DEL, mp);
- mp->faceid = clib_host_to_net_u32 (faceid);
-
- //send it...
- S (mp);
-
- //Wait for a reply...
- W (ret);
-
- return ret;
-}
-
-static int
-api_hicn_api_face_ip_params_get (vat_main_t * vam)
-{
- unformat_input_t *input = vam->input;
- vl_api_hicn_api_face_ip_params_get_t *mp;
+ vl_api_hicn_api_face_params_get_t *mp;
u32 faceid = HICN_FACE_NULL, ret;
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
@@ -728,7 +461,7 @@ api_hicn_api_face_ip_params_get (vat_main_t * vam)
return 1;
}
//Construct the API message
- M (HICN_API_FACE_IP_PARAMS_GET, mp);
+ M (HICN_API_FACE_PARAMS_GET, mp);
mp->faceid = clib_host_to_net_u32 (faceid);
//send it...
@@ -741,14 +474,13 @@ api_hicn_api_face_ip_params_get (vat_main_t * vam)
}
static void
- vl_api_hicn_api_face_ip_params_get_reply_t_handler
- (vl_api_hicn_api_face_ip_params_get_reply_t * rmp)
+ vl_api_hicn_api_face_params_get_reply_t_handler
+ (vl_api_hicn_api_face_params_get_reply_t * rmp)
{
vat_main_t *vam = hicn_test_main.vat_main;
i32 retval = ntohl (rmp->retval);
u8 *sbuf = 0;
- ip46_address_t remote_addr;
- ip46_address_t local_addr;
+ ip46_address_t nat_addr;
if (vam->async_mode)
{
@@ -765,12 +497,10 @@ static void
return;
}
vec_reset_length (sbuf);
- ip_address_decode (&rmp->local_addr, &local_addr);
- ip_address_decode (&rmp->remote_addr, &remote_addr);
+ ip_address_decode (&rmp->nat_addr, &nat_addr);
sbuf =
- format (0, "local_addr %U remote_addr %U", format_ip46_address,
- &local_addr, 0 /*IP46_ANY_TYPE */ , format_ip46_address,
- &remote_addr, 0 /*IP46_ANY_TYPE */ );
+ format (0, "nat_addr %U", format_ip46_address,
+ &nat_addr, 0 /*IP46_ANY_TYPE */);
fformat (vam->ofp, "%s swif %d flags %d\n",
sbuf,
@@ -779,48 +509,23 @@ static void
}
static void
-format_ip_face (vl_api_hicn_face_ip_t * rmp)
+format_face (vl_api_hicn_face_t * rmp)
{
vat_main_t *vam = hicn_test_main.vat_main;
u8 *sbuf = 0;
- ip46_address_t remote_addr;
+ ip46_address_t nat_addr;
ip46_address_t local_addr;
vec_reset_length (sbuf);
- ip_address_decode (&rmp->local_addr, &local_addr);
- ip_address_decode (&rmp->remote_addr, &remote_addr);
- sbuf =
- format (0, "local_addr %U remote_addr %U", format_ip46_address,
- &local_addr, 0 /*IP46_ANY_TYPE */ , format_ip46_address,
- &remote_addr, 0 /*IP46_ANY_TYPE */ );
-
- fformat (vam->ofp, "%s swif %d flags %d name %s\n",
- sbuf,
- clib_net_to_host_u32 (rmp->swif),
- clib_net_to_host_i32 (rmp->flags), rmp->if_name);
-}
-
-static void
-format_udp_face (vl_api_hicn_face_udp_t * rmp)
-{
- vat_main_t *vam = hicn_test_main.vat_main;
- u8 *sbuf = 0;
- ip46_address_t remote_addr;
- ip46_address_t local_addr;
+ ip_address_decode (&rmp->nat_addr, &nat_addr);
- vec_reset_length (sbuf);
- ip_address_decode (&rmp->local_addr, &local_addr);
- ip_address_decode (&rmp->remote_addr, &remote_addr);
- u16 lport = clib_net_to_host_u16 (rmp->lport);
- u16 rport = clib_net_to_host_u16 (rmp->rport);;
sbuf =
- format (0, "local_addr %U port %u remote_addr %U port %u",
- format_ip46_address, &local_addr, 0 /*IP46_ANY_TYPE */ , lport,
- format_ip46_address, &remote_addr, 0 /*IP46_ANY_TYPE */ , rport);
+ format (0, "nat_addr %U", format_ip46_address,
+ &local_addr, 0 /*IP46_ANY_TYPE */);
fformat (vam->ofp, "%s swif %d flags %d name %s\n",
sbuf,
- clib_net_to_host_u16 (rmp->swif),
+ clib_net_to_host_u32 (rmp->swif),
clib_net_to_host_i32 (rmp->flags), rmp->if_name);
}
@@ -841,6 +546,9 @@ api_hicn_api_faces_dump (vat_main_t * vam)
M (HICN_API_FACES_DUMP, mp);
S (mp);
+ if (!hm->ping_id)
+ hm->ping_id = vl_msg_api_get_msg_index ((u8 *) (VL_API_CONTROL_PING_CRC));
+
/* Use a control ping for synchronization */
mp_ping = vl_msg_api_alloc_as_if_client (sizeof (*mp_ping));
mp_ping->_vl_msg_id = htons (hm->ping_id);
@@ -859,14 +567,7 @@ static void
vl_api_hicn_api_faces_details_t_handler
(vl_api_hicn_api_faces_details_t * mp)
{
- if (mp->type == IP_FACE)
- {
- format_ip_face (&(mp->face.ip));
- }
- else
- {
- format_udp_face (&(mp->face.udp));
- }
+ format_face (&(mp->face));
}
static int
@@ -929,15 +630,7 @@ static void
fformat (vam->ofp, " (API call error: %d)\n", vam->retval);
return;
}
-
- if (rmp->type == IP_FACE)
- {
- format_ip_face (&(rmp->face.ip));
- }
- else
- {
- format_udp_face (&(rmp->face.udp));
- }
+ format_face (&(rmp->face));
}
@@ -959,6 +652,9 @@ api_hicn_api_face_stats_dump (vat_main_t * vam)
M (HICN_API_FACE_STATS_DUMP, mp);
S (mp);
+ if (!hm->ping_id)
+ hm->ping_id = vl_msg_api_get_msg_index ((u8 *) (VL_API_CONTROL_PING_CRC));
+
/* Use a control ping for synchronization */
mp_ping = vl_msg_api_alloc_as_if_client (sizeof (*mp_ping));
mp_ping->_vl_msg_id = htons (hm->ping_id);
@@ -1061,6 +757,9 @@ api_hicn_api_routes_dump (vat_main_t * vam)
M (HICN_API_ROUTES_DUMP, mp);
S (mp);
+ if (!hm->ping_id)
+ hm->ping_id = vl_msg_api_get_msg_index ((u8 *) (VL_API_CONTROL_PING_CRC));
+
/* Use a control ping for synchronization */
mp_ping = vl_msg_api_alloc_as_if_client (sizeof (*mp_ping));
mp_ping->_vl_msg_id = htons (hm->ping_id);
@@ -1151,152 +850,6 @@ static void
}
static int
-api_hicn_api_route_nhops_add (vat_main_t * vam)
-{
- unformat_input_t *input = vam->input;
- vl_api_hicn_api_route_nhops_add_t *mp;
-
- fib_prefix_t prefix;
- u32 faceid = 0;
- int ret;
-
-
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (input, "add prefix %U/%d", unformat_ip46_address,
- &prefix.fp_addr, IP46_TYPE_ANY, &prefix.fp_len))
- {;
- }
- else if (unformat (input, "face %d", &faceid))
- {;
- }
- else
- {
- break;
- }
- }
-
- /* Check parse */
- if (((prefix.fp_addr.as_u64[0] == 0) && (prefix.fp_addr.as_u64[1] == 0))
- || (prefix.fp_len == 0) || (faceid == 0))
- {
- clib_warning ("Please specify prefix and faceid...");
- return 1;
- }
- /* Construct the API message */
- M (HICN_API_ROUTE_NHOPS_ADD, mp);
- ip_prefix_encode (&prefix, &mp->prefix);
-
- if (!ip46_address_is_ip4 (&(prefix.fp_addr)))
- prefix.fp_proto = fib_proto_from_ip46 (IP46_TYPE_IP6);
-
- mp->face_ids[0] = clib_host_to_net_u32 (faceid);
- mp->n_faces = 1;
-
- /* send it... */
- S (mp);
-
- /* Wait for a reply... */
- W (ret);
-
- return ret;
-}
-
-static int
-api_hicn_api_route_del (vat_main_t * vam)
-{
- unformat_input_t *input = vam->input;
- vl_api_hicn_api_route_del_t *mp;
-
- fib_prefix_t prefix;
- int ret;
-
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (input, "prefix %U/%d", unformat_ip46_address,
- &prefix.fp_addr, IP46_TYPE_ANY, &prefix.fp_len))
- {;
- }
- else
- {
- break;
- }
- }
-
- /* Check parse */
- if (((prefix.fp_addr.as_u64[0] == 0) && (prefix.fp_addr.as_u64[1] == 0))
- || (prefix.fp_len == 0))
- {
- clib_warning ("Please specify prefix...");
- return 1;
- }
- /* Construct the API message */
- M (HICN_API_ROUTE_DEL, mp);
- ip_prefix_encode (&prefix, &mp->prefix);
-
- if (!ip46_address_is_ip4 (&(prefix.fp_addr)))
- prefix.fp_proto = fib_proto_from_ip46 (IP46_TYPE_IP6);
-
- /* send it... */
- S (mp);
-
- /* Wait for a reply... */
- W (ret);
-
- return ret;
-
-}
-
-static int
-api_hicn_api_route_nhop_del (vat_main_t * vam)
-{
- unformat_input_t *input = vam->input;
- vl_api_hicn_api_route_nhop_del_t *mp;
-
- fib_prefix_t prefix;
- int faceid = 0, ret;
-
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (input, "del prefix %U/%d", unformat_ip46_address,
- &prefix.fp_addr, IP46_TYPE_ANY, &prefix.fp_len))
- {;
- }
- else if (unformat (input, "face %d", &faceid))
- {;
- }
- else
- {
- break;
- }
- }
-
- /* Check parse */
- if (((prefix.fp_addr.as_u64[0] == 0) && (prefix.fp_addr.as_u64[1] == 0))
- || (prefix.fp_len == 0) || (faceid == HICN_FACE_NULL))
- {
- clib_warning ("Please specify prefix and faceid...");
- return 1;
- }
- /* Construct the API message */
- M (HICN_API_ROUTE_NHOP_DEL, mp);
- ip_prefix_encode (&prefix, &mp->prefix);
-
- if (!ip46_address_is_ip4 (&(prefix.fp_addr)))
- prefix.fp_proto = fib_proto_from_ip46 (IP46_TYPE_IP6);
-
- mp->faceid = clib_host_to_net_u32 (faceid);
-
- /* send it... */
- S (mp);
-
- /* Wait for a reply... */
- W (ret);
-
- return ret;
-}
-
-static int
api_hicn_api_strategies_get (vat_main_t * vam)
{
vl_api_hicn_api_strategies_get_t *mp;
@@ -1415,6 +968,58 @@ static void
}
static int
+api_hicn_api_enable_disable (vat_main_t * vam)
+{
+ unformat_input_t *input = vam->input;
+ vl_api_hicn_api_enable_disable_t *mp;
+ int ret;
+
+ fib_prefix_t prefix;
+ vl_api_hicn_action_type_t en_dis = HICN_ENABLE;
+
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (input, "prefix %U/%d", unformat_ip46_address,
+ &prefix.fp_addr, IP46_TYPE_ANY, &prefix.fp_len))
+ {;
+ }
+ else if (unformat (input, "disable"))
+ {;
+ en_dis = HICN_DISABLE;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ /* Check parse */
+ if (((prefix.fp_addr.as_u64[0] == 0) && (prefix.fp_addr.as_u64[1] == 0))
+ || (prefix.fp_len == 0))
+ {
+ clib_warning ("Please specify a valid prefix...");
+ return 1;
+ }
+
+ prefix.fp_proto = ip46_address_is_ip4 (&(prefix.fp_addr)) ? FIB_PROTOCOL_IP4 :
+ FIB_PROTOCOL_IP6;
+
+ //Construct the API message
+ M (HICN_API_ENABLE_DISABLE, mp);
+
+ ip_prefix_encode (&prefix, &mp->prefix);
+ mp->enable_disable = en_dis;
+
+ //send it...
+ S (mp);
+
+ //Wait for a reply...
+ W (ret);
+
+ return ret;
+}
+
+static int
api_hicn_api_register_prod_app (vat_main_t * vam)
{
unformat_input_t *input = vam->input;
@@ -1607,12 +1212,104 @@ static void
fformat (vam->ofp,
"ip4 address %U\n"
- "ip6 address :%U\n"
- "appif id :%d\n",
+ "ip6 address :%U\n",
format_ip46_address, IP46_TYPE_ANY, &src_addr4,
format_ip46_address, IP46_TYPE_ANY, &src_addr6);
}
+static int
+api_hicn_api_udp_tunnel_add_del (vat_main_t * vam)
+{
+ unformat_input_t *input = vam->input;
+ vl_api_hicn_api_udp_tunnel_add_del_t *mp;
+
+ ip46_address_t src_ip, dst_ip;
+ u32 src_port, dst_port;
+ fib_protocol_t fproto;
+ u8 is_del;
+ int ret;
+
+ is_del = 0;
+ fproto = FIB_PROTOCOL_MAX;
+
+ /* Get a line of input. */
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (input, "add"))
+ is_del = 0;
+ else if (unformat (input, "del"))
+ is_del = 1;
+ else if (unformat (input, "%U %U",
+ unformat_ip4_address,
+ &src_ip.ip4, unformat_ip4_address, &dst_ip.ip4))
+ fproto = FIB_PROTOCOL_IP4;
+ else if (unformat (input, "%U %U",
+ unformat_ip6_address,
+ &src_ip.ip6, unformat_ip6_address, &dst_ip.ip6))
+ fproto = FIB_PROTOCOL_IP6;
+ else if (unformat (input, "%d %d", &src_port, &dst_port))
+ ;
+ else
+ {
+ break;
+ }
+ }
+
+
+ if (fproto == FIB_PROTOCOL_MAX)
+ {
+ clib_warning ("Please specify face ID");
+ return 1;
+ }
+
+ /* Construct the API message */
+ M (HICN_API_UDP_TUNNEL_ADD_DEL, mp);
+ ip_address_encode (&src_ip, fproto == FIB_PROTOCOL_IP4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6 ,&mp->src_addr);
+ ip_address_encode (&dst_ip, fproto == FIB_PROTOCOL_IP4 ? IP46_TYPE_IP4 : IP46_TYPE_IP6 ,&mp->dst_addr);
+ mp->src_port = clib_host_to_net_u16(src_port);
+ mp->dst_port = clib_host_to_net_u16(dst_port);
+ mp->is_add = !is_del;
+
+ /* send it... */
+ S (mp);
+
+ /* Wait for a reply... */
+ W (ret);
+
+ return ret;
+}
+
+static void
+vl_api_hicn_api_udp_tunnel_add_del_reply_t_handler
+(vl_api_hicn_api_udp_tunnel_add_del_reply_t * mp)
+{
+ vat_main_t *vam = hicn_test_main.vat_main;
+ i32 retval = ntohl (mp->retval);
+
+ if (vam->async_mode)
+ {
+ vam->async_errors += (retval < 0);
+ return;
+ }
+ vam->retval = retval;
+ vam->result_ready = 1;
+
+ if (vam->retval < 0)
+ {
+ //vpp_api_test infra will also print out string form of error
+ fformat (vam->ofp, " (API call error: %d)\n", vam->retval);
+ return;
+ }
+
+ index_t uei = clib_net_to_host_u32(mp->uei);
+
+ fformat (vam->ofp,
+ "udp-encap %d\n",
+ uei);
+}
+
+
+
#include <hicn/hicn.api_test.c>
/*
diff --git a/hicn-plugin/src/hicn_msg_enum.h b/hicn-plugin/src/hicn_msg_enum.h
index 291e6226c..fcf2a1e87 100644
--- a/hicn-plugin/src/hicn_msg_enum.h
+++ b/hicn-plugin/src/hicn_msg_enum.h
@@ -18,6 +18,9 @@
#include <vppinfra/byte_order.h>
+/**
+ * @file
+ */
#define vl_msg_id(n, h) n,
typedef enum
{
diff --git a/hicn-plugin/src/infra.h b/hicn-plugin/src/infra.h
index b859b8e46..ff76de4e4 100644
--- a/hicn-plugin/src/infra.h
+++ b/hicn-plugin/src/infra.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -18,12 +18,17 @@
#include <vlib/vlib.h>
#include <vnet/vnet.h>
+#include <vnet/interface.h>
#include "pcs.h"
/**
- * hICN plugin global state: see also
- * - fib and pits
+ * @file infra.h
+ *
+ */
+
+/**
+ * @brief hICN plugin global state.
*/
typedef struct hicn_main_s
{
@@ -43,6 +48,8 @@ typedef struct hicn_main_s
*/
u64 pit_lifetime_max_ms;
+ vnet_link_t link;
+
} hicn_main_t;
extern hicn_main_t hicn_main;
@@ -67,7 +74,8 @@ int
hicn_infra_plugin_enable_disable (int enable_disable,
int pit_max_size,
f64 pit_max_lifetime_sec_req,
- int cs_max_size, int cs_reserved_app);
+ int cs_max_size,
+ vnet_link_t link);
/* vlib nodes that compose the hICN forwarder */
@@ -80,6 +88,9 @@ extern vlib_node_registration_t hicn_interest_hitcs_node;
extern vlib_node_registration_t hicn_pg_interest_node;
extern vlib_node_registration_t hicn_pg_data_node;
extern vlib_node_registration_t hicn_pg_server_node;
+extern vlib_node_registration_t hicn_data_input_ip6_node;
+extern vlib_node_registration_t hicn_data_input_ip4_node;
+
#endif /* // __HICN_INFRA_H__ */
diff --git a/hicn-plugin/src/interest_hitcs.h b/hicn-plugin/src/interest_hitcs.h
index c69564452..94fa3e6f5 100644
--- a/hicn-plugin/src/interest_hitcs.h
+++ b/hicn-plugin/src/interest_hitcs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -21,6 +21,16 @@
#include "pcs.h"
+/**
+ * @file interest_hitcs.h
+ *
+ * This is the node encoutered by interest packets after the hicn-interest-pcslookup.
+ * This node satisfies an interest with a data stored in the CS and send the data back
+ * from the incoming iface of the interest (i.e., the vlib buffer is sent to the
+ * hicn6-iface-output or hicn4-iface-output node). In case the data is expired, the
+ * vlib buffer is sent to the hicn-strategy node.
+ */
+
/*
* Node context data; we think this is per-thread/instance
*/
@@ -41,9 +51,9 @@ typedef struct
typedef enum
{
HICN_INTEREST_HITCS_NEXT_STRATEGY,
- HICN_INTEREST_HITCS_NEXT_PUSH,
+ HICN_INTEREST_HITCS_NEXT_IFACE4_OUT,
+ HICN_INTEREST_HITCS_NEXT_IFACE6_OUT,
HICN_INTEREST_HITCS_NEXT_ERROR_DROP,
- HICN_INTEREST_HITCS_NEXT_EMPTY,
HICN_INTEREST_HITCS_N_NEXT,
} hicn_interest_hitcs_next_t;
diff --git a/hicn-plugin/src/interest_hitcs_node.c b/hicn-plugin/src/interest_hitcs_node.c
index d10f15afa..f569fa897 100644
--- a/hicn-plugin/src/interest_hitcs_node.c
+++ b/hicn-plugin/src/interest_hitcs_node.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -184,9 +184,9 @@ hicn_interest_hitcs_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
* Retrieve the incoming iface and forward
* the data through it
*/
- next0 = hicnb0->face_dpo_id.dpoi_next_node;
- vnet_buffer (b0)->ip.adj_index[VLIB_TX] =
- hicnb0->face_dpo_id.dpoi_index;
+ next0 = isv6 ? HICN_INTEREST_HITCS_NEXT_IFACE6_OUT :
+ HICN_INTEREST_HITCS_NEXT_IFACE4_OUT;
+ vnet_buffer (b0)->ip.adj_index[VLIB_TX] = hicnb0->face_id;
clone_from_cs (vm, &pitp->u.cs.cs_pkt_buf, b0, isv6);
@@ -277,9 +277,9 @@ VLIB_REGISTER_NODE(hicn_interest_hitcs_node) =
.next_nodes =
{
[HICN_INTEREST_HITCS_NEXT_STRATEGY] = "hicn-strategy",
- [HICN_INTEREST_HITCS_NEXT_PUSH] = "hicn-data-push",
- [HICN_INTEREST_HITCS_NEXT_ERROR_DROP] = "error-drop",
- [HICN_INTEREST_HITCS_NEXT_EMPTY] = "ip6-lookup"
+ [HICN_INTEREST_HITCS_NEXT_IFACE4_OUT] = "hicn4-iface-output",
+ [HICN_INTEREST_HITCS_NEXT_IFACE6_OUT] = "hicn6-iface-output",
+ [HICN_INTEREST_HITCS_NEXT_ERROR_DROP] = "error-drop"
},
};
/* *INDENT-ON* */
diff --git a/hicn-plugin/src/interest_hitpit.h b/hicn-plugin/src/interest_hitpit.h
index fc4cfc3ea..ffdc61c8f 100644
--- a/hicn-plugin/src/interest_hitpit.h
+++ b/hicn-plugin/src/interest_hitpit.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -21,6 +21,17 @@
#include "pcs.h"
+/**
+ * @file interest_hitpit.h
+ *
+ * This is the node encoutered by interest packets after the hicn-interest-pcslookup.
+ * This node aggregates an interest in the PIT or forward it in case of a retransmission.
+ * If the interest must be retransmitted the next vlib node will be on of the
+ * hicn6-face-output or hicn4-face-output nodes. If the pit entry is expired the next vlib node
+ * will be the hicn-strategy node, otherwise the vlib buffer is dropped.
+ */
+
+
/*
* Node context data; we think this is per-thread/instance
*/
@@ -42,6 +53,8 @@ typedef enum
{
HICN_INTEREST_HITPIT_NEXT_INTEREST_HITCS,
HICN_INTEREST_HITPIT_NEXT_STRATEGY,
+ HICN_INTEREST_HITPIT_NEXT_FACE4_OUTPUT,
+ HICN_INTEREST_HITPIT_NEXT_FACE6_OUTPUT,
HICN_INTEREST_HITPIT_NEXT_ERROR_DROP,
HICN_INTEREST_HITPIT_N_NEXT,
} hicn_interest_hitpit_next_t;
diff --git a/hicn-plugin/src/interest_hitpit_node.c b/hicn-plugin/src/interest_hitpit_node.c
index a346dcc7e..9ebf183c5 100644
--- a/hicn-plugin/src/interest_hitpit_node.c
+++ b/hicn-plugin/src/interest_hitpit_node.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -88,7 +88,7 @@ hicn_interest_hitpit_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
u8 dpo_ctx_id0;
u8 found = 0;
int nh_idx;
- dpo_id_t *outface;
+ hicn_face_id_t outface;
hicn_hash_entry_t *hash_entry0;
hicn_buffer_t *hicnb0;
int ret;
@@ -166,7 +166,7 @@ hicn_interest_hitpit_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
*/
found =
- hicn_face_search (&(hicnb0->face_dpo_id),
+ hicn_face_search (hicnb0->face_id,
&(pitp->u.pit.faces));
if (found)
@@ -178,9 +178,10 @@ hicn_interest_hitpit_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
* Prepare the packet for the
* forwarding
*/
- next0 = outface->dpoi_next_node;
+ next0 = isv6 ? HICN_INTEREST_HITPIT_NEXT_FACE6_OUTPUT :
+ HICN_INTEREST_HITPIT_NEXT_FACE4_OUTPUT;
vnet_buffer (b0)->ip.adj_index[VLIB_TX] =
- outface->dpoi_index;
+ outface;
/*
* Update the egress face in
@@ -191,8 +192,8 @@ hicn_interest_hitpit_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
}
else
{
- hicn_face_db_add_face_dpo (&hicnb0->face_dpo_id,
- &pitp->u.pit.faces);
+ hicn_face_db_add_face (hicnb0->face_id,
+ &pitp->u.pit.faces);
/* Aggregation */
drop_packet (&next0);
@@ -293,6 +294,8 @@ VLIB_REGISTER_NODE(hicn_interest_hitpit_node) =
{
[HICN_INTEREST_HITPIT_NEXT_INTEREST_HITCS] = "hicn-interest-hitcs",
[HICN_INTEREST_HITPIT_NEXT_STRATEGY] = "hicn-strategy",
+ [HICN_INTEREST_HITPIT_NEXT_FACE4_OUTPUT] = "hicn4-face-output",
+ [HICN_INTEREST_HITPIT_NEXT_FACE6_OUTPUT] = "hicn6-face-output",
[HICN_INTEREST_HITPIT_NEXT_ERROR_DROP] = "error-drop",
},
};
diff --git a/hicn-plugin/src/interest_pcslookup.h b/hicn-plugin/src/interest_pcslookup.h
index 5a5a6a7a8..cbc9dde51 100644
--- a/hicn-plugin/src/interest_pcslookup.h
+++ b/hicn-plugin/src/interest_pcslookup.h
@@ -21,6 +21,17 @@
#include "pcs.h"
+/**
+ * @file interest_pcslookup.h
+ *
+ * This is the node encoutered by interest packets after the hicn6-iface-input or
+ * hicn4-iface-input. This node performs a lookup in the pit and content store and
+ * if there is a hit in the PIT, the vlib buffer is passed to the hicn-interest-hitcs
+ * while if there is a hit in the CS the vlib buffer is passed to the
+ * hicn-interest-hitpit. If there isn't any hit, the vlib buffer is passed to the
+ * hicn-strategy node.
+ */
+
/*
* Node context data; we think this is per-thread/instance
*/
diff --git a/hicn-plugin/src/mapme.h b/hicn-plugin/src/mapme.h
index 071590ede..17bd9a766 100644
--- a/hicn-plugin/src/mapme.h
+++ b/hicn-plugin/src/mapme.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -18,13 +18,34 @@
#include <vnet/dpo/load_balance.h>
#include <vnet/buffer.h>
-//#include <hicn/hicn.h>
#include <hicn/mapme.h>
#include "hicn.h"
+#include "route.h"
#include "strategy_dpo_ctx.h"
#include "strategy_dpo_manager.h" // dpo_is_hicn
+/**
+ * @file
+ *
+ * @brief Mapme
+ *
+ * Mapme implementation follows the "Anchorless mobility through hICN" document
+ * specification. In particular, the implementation is made of:
+ * - two internal nodes: hicn-mapme-ctrl and hicn-mapme-ack. The former processes
+ * IU and the latter IU acknowledgment.
+ * - a process node, mapme-eventmgr-process, that is signaled every time a face is
+ * added or deleted, as well as when a new next hop is added to a fib entry as a
+ * result of a mobility event.
+ *
+ * TFIB implementation is done as an extension of an hICN fib entry. In particular,
+ * the list of next hops hold the list of next hops in the tfib as well (stored at the
+ * end of the list of regualt next hops). Mapme implementation follows the hICN vrf
+ * implementation and consider the vrf 0 (default fib) as the control-plane fib to
+ * update every time a new next hop must be added or removed.
+ */
+
+
#define HICN_MAPME_ALLOW_LOCATORS 1
//#define HICN_MAPME_NOTIFICATIONS 1
@@ -34,6 +55,9 @@
#define INVALID_SEQ 0
+STATIC_ASSERT (sizeof(u32) == sizeof(seq_t),
+ "seq_t is not 4 bytes");
+
typedef struct hicn_mapme_conf_s
{
hicn_mapme_conf_t conf;
@@ -43,6 +67,9 @@ typedef struct hicn_mapme_conf_s
vlib_log_class_t log_class;
} hicn_mapme_main_t;
+/**
+ * @brief List of event to signat to the procesing node (eventmgr)
+ */
#define foreach_hicn_mapme_event \
_(FACE_ADD) \
_(FACE_DEL) \
@@ -72,13 +99,24 @@ typedef hicn_dpo_ctx_t hicn_mapme_tfib_t;
STATIC_ASSERT (sizeof (hicn_mapme_tfib_t) <= sizeof (hicn_dpo_ctx_t),
"hicn_mapme_tfib_t is greater than hicn_dpo_ctx_t");
-#define TFIB(dpo) ((hicn_mapme_tfib_t*)(dpo))
+#define TFIB(dpo_ctx) ((hicn_mapme_tfib_t*)(dpo_ctx))
static_always_inline int
-hicn_mapme_nh_set (hicn_mapme_tfib_t * tfib, dpo_id_t * face_id)
+hicn_mapme_nh_set (hicn_mapme_tfib_t * tfib, hicn_face_id_t face_id)
{
- tfib->next_hops[0] = *face_id;
- tfib->entry_count = 1;
+ hicn_dpo_ctx_t * strategy_ctx = (hicn_dpo_ctx_t *)tfib;
+ const fib_prefix_t * prefix = fib_entry_get_prefix(strategy_ctx->fib_entry_index);
+
+ u32 n_entries = tfib->entry_count;
+ /* Remove all the existing next hops and set the new one */
+ for (int i = 0; i < n_entries; i++)
+ {
+ hicn_face_t * face = hicn_dpoi_get_from_idx(strategy_ctx->next_hops[0]);
+ ip_adjacency_t * adj = adj_get (face->dpo.dpoi_index);
+ ip_nh_del_helper(face->dpo.dpoi_proto, prefix, &adj->sub_type.nbr.next_hop, face->sw_if);
+ }
+ hicn_face_t * face = hicn_dpoi_get_from_idx(face_id);
+ ip_nh_add_helper(face->dpo.dpoi_proto, prefix, &face->nat_addr, face->sw_if);
return 0;
}
@@ -86,12 +124,18 @@ hicn_mapme_nh_set (hicn_mapme_tfib_t * tfib, dpo_id_t * face_id)
* @brief Add a next hop iif it is not already a next hops
*/
static_always_inline int
-hicn_mapme_nh_add (hicn_mapme_tfib_t * tfib, dpo_id_t * face_id)
+hicn_mapme_nh_add (hicn_mapme_tfib_t * tfib, hicn_face_id_t face_id)
{
for (u8 pos = 0; pos < tfib->entry_count; pos++)
- if (dpo_cmp (&tfib->next_hops[pos], face_id) == 0)
+ if (tfib->next_hops[pos] == face_id)
return 0;
- tfib->next_hops[tfib->entry_count++] = *face_id;
+
+ /* Add the next hop in the vrf 0 which will add it to the entry in the hICN vrf */
+ hicn_dpo_ctx_t * strategy_ctx = (hicn_dpo_ctx_t *)tfib;
+ const fib_prefix_t * prefix = fib_entry_get_prefix(strategy_ctx->fib_entry_index);
+ hicn_face_t * face = hicn_dpoi_get_from_idx(face_id);
+ ip_nh_add_helper(face->dpo.dpoi_proto, prefix, &face->nat_addr, face->sw_if);
+
return 0;
}
@@ -101,30 +145,36 @@ hicn_mapme_nh_add (hicn_mapme_tfib_t * tfib, dpo_id_t * face_id)
* XXX we should have the for look in the reverse order for simpler code.
*/
static_always_inline int
-hicn_mapme_tfib_add (hicn_mapme_tfib_t * tfib, dpo_id_t * face_id)
+hicn_mapme_tfib_add (hicn_mapme_tfib_t * tfib, hicn_face_id_t face_id)
{
u8 pos = HICN_PARAM_FIB_ENTRY_NHOPS_MAX - tfib->tfib_entry_count;
//XXX don 't add if it already exist
// eg.an old IU received on a face on which we are retransmitting
for (u8 pos2 = pos; pos2 < HICN_PARAM_FIB_ENTRY_NHOPS_MAX; pos2++)
- if (dpo_cmp (&tfib->next_hops[pos2], face_id) == 0)
+ if (tfib->next_hops[pos2] == face_id)
return 0;
//Make sure we have enough room
if (pos <= tfib->entry_count)
return -1;
- tfib->next_hops[pos - 1] = *face_id;
+ tfib->next_hops[pos - 1] = face_id;
tfib->tfib_entry_count++;
+ /*
+ * Take a lock on the face as if it will be removed from the next_hops a
+ * lock will be removed.
+ */
+ hicn_face_lock_with_id(face_id);
+
return 0;
}
static_always_inline int
hicn_mapme_tfib_clear (hicn_mapme_tfib_t * tfib)
{
- dpo_id_t invalid = NEXT_HOP_INVALID;
+ hicn_face_id_t invalid = NEXT_HOP_INVALID;
/*
* We need to do a linear scan of TFIB entries to find the one to
* remove
@@ -133,7 +183,7 @@ hicn_mapme_tfib_clear (hicn_mapme_tfib_t * tfib)
u8 pos = ~0;
for (pos = start_pos; pos < HICN_PARAM_FIB_ENTRY_NHOPS_MAX; pos++)
{
- hicn_face_unlock (&tfib->next_hops[pos]);
+ hicn_face_unlock_with_id (tfib->next_hops[pos]);
tfib->next_hops[pos] = invalid;
break;
}
@@ -144,9 +194,9 @@ hicn_mapme_tfib_clear (hicn_mapme_tfib_t * tfib)
}
static_always_inline int
-hicn_mapme_tfib_del (hicn_mapme_tfib_t * tfib, dpo_id_t * face_id)
+hicn_mapme_tfib_del (hicn_mapme_tfib_t * tfib, hicn_face_id_t face_id)
{
- dpo_id_t invalid = NEXT_HOP_INVALID;
+ hicn_face_id_t invalid = NEXT_HOP_INVALID;
/*
* We need to do a linear scan of TFIB entries to find the one to
* remove
@@ -154,9 +204,9 @@ hicn_mapme_tfib_del (hicn_mapme_tfib_t * tfib, dpo_id_t * face_id)
u8 start_pos = HICN_PARAM_FIB_ENTRY_NHOPS_MAX - tfib->tfib_entry_count;
u8 pos = ~0;
for (pos = start_pos; pos < HICN_PARAM_FIB_ENTRY_NHOPS_MAX; pos++)
- if (dpo_cmp (&tfib->next_hops[pos], face_id) == 0)
+ if (tfib->next_hops[pos] == face_id)
{
- hicn_face_unlock (&tfib->next_hops[pos]);
+ hicn_face_unlock_with_id (tfib->next_hops[pos]);
tfib->next_hops[pos] = invalid;
break;
}
@@ -168,8 +218,8 @@ hicn_mapme_tfib_del (hicn_mapme_tfib_t * tfib, dpo_id_t * face_id)
/* Likely we won't receive a new IU twice from the same face */
if (PREDICT_TRUE (pos > start_pos))
- memmove (tfib->next_hops + start_pos, tfib->next_hops + start_pos + 1,
- (pos - start_pos) * sizeof (dpo_id_t));
+ memmove (tfib->next_hops + start_pos +1 , tfib->next_hops + start_pos,
+ (pos - start_pos) * sizeof (hicn_face_id_t));
return 0;
}
@@ -287,34 +337,17 @@ hicn_mapme_get_dpo_vlib_edge (dpo_id_t * dpo)
* @brief Returns the next hop node on which we can send an Update packet
*/
always_inline char *
-hicn_mapme_get_dpo_face_node (dpo_id_t * dpo)
+hicn_mapme_get_dpo_face_node (hicn_face_id_t face_id)
{
- if (dpo->dpoi_type == hicn_face_ip_type)
- {
- switch (dpo->dpoi_proto)
- {
- case DPO_PROTO_IP4:
- return "hicn-face-ip4-output";
- case DPO_PROTO_IP6:
- return "hicn-face-ip6-output";
- default:
- return NULL;
- }
- }
- else if (dpo->dpoi_type == hicn_face_udp_type)
- {
- switch (dpo->dpoi_proto)
- {
- case DPO_PROTO_IP4:
- return "hicn-face-udp4-output";
- case DPO_PROTO_IP6:
- return "hicn-face-udp6-output";
- default:
- return NULL;
- }
- }
- else
+ hicn_face_t * face = hicn_dpoi_get_from_idx(face_id);
+
+ switch (face->dpo.dpoi_proto)
{
+ case DPO_PROTO_IP4:
+ return "hicn4-face-output";
+ case DPO_PROTO_IP6:
+ return "hicn6-face-output";
+ default:
return NULL;
}
}
diff --git a/hicn-plugin/src/mapme_ack.h b/hicn-plugin/src/mapme_ack.h
index 98a219982..821baf203 100644
--- a/hicn-plugin/src/mapme_ack.h
+++ b/hicn-plugin/src/mapme_ack.h
@@ -24,6 +24,11 @@
#include <vlib/vlib.h>
#include <vnet/vnet.h>
+/**
+ * @file
+ *
+ */
+
/* Node context data */
typedef struct hicn_mapme_ack_runtime_s
{
diff --git a/hicn-plugin/src/mapme_ack_node.c b/hicn-plugin/src/mapme_ack_node.c
index 557fb0ad7..f26895d20 100644
--- a/hicn-plugin/src/mapme_ack_node.c
+++ b/hicn-plugin/src/mapme_ack_node.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -48,7 +48,7 @@ static char *hicn_mapme_ack_error_strings[] = {
*/
bool
hicn_mapme_process_ack (vlib_main_t * vm, vlib_buffer_t * b,
- dpo_id_t * in_face)
+ hicn_face_id_t in_face)
{
seq_t fib_seq;
const dpo_id_t *dpo;
@@ -113,8 +113,11 @@ hicn_mapme_process_ack (vlib_main_t * vm, vlib_buffer_t * b,
1,
sizeof (retx_t));
*retx = (retx_t)
- {
- .prefix = prefix,.dpo = *dpo};
+ {
+ .prefix = prefix,
+ .dpo = *dpo
+ };
+
return true;
ERR_PARSE:
@@ -159,7 +162,7 @@ hicn_mapme_ack_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
vlib_cli_output (vm, "Received IUAck");
hb = hicn_get_buffer (b0);
- hicn_mapme_process_ack (vm, b0, &hb->face_dpo_id);
+ hicn_mapme_process_ack (vm, b0, hb->face_id);
/* Single loop: process 1 packet here */
sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
diff --git a/hicn-plugin/src/mapme_ctrl.h b/hicn-plugin/src/mapme_ctrl.h
index e7c1cdf64..9af4beccc 100644
--- a/hicn-plugin/src/mapme_ctrl.h
+++ b/hicn-plugin/src/mapme_ctrl.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -24,6 +24,11 @@
#include <vlib/vlib.h>
#include <vnet/vnet.h>
+/**
+ * @file mapme_ctrl.h
+ *
+ */
+
/* Node context data */
typedef struct hicn_mapme_ctrl_runtime_s
{
@@ -42,8 +47,6 @@ typedef enum
{
HICN_MAPME_CTRL_NEXT_IP4_OUTPUT,
HICN_MAPME_CTRL_NEXT_IP6_OUTPUT,
- HICN_MAPME_CTRL_NEXT_UDP46_OUTPUT,
- HICN_MAPME_CTRL_NEXT_UDP66_OUTPUT,
HICN_MAPME_CTRL_NEXT_ERROR_DROP,
HICN_MAPME_CTRL_N_NEXT,
} hicn_mapme_ctrl_next_t;
@@ -51,34 +54,17 @@ typedef enum
* @brief Returns the next hop node on which we can send an ACK packet
*/
always_inline hicn_mapme_ctrl_next_t
-hicn_mapme_get_dpo_iface_node (dpo_id_t * dpo)
+hicn_mapme_ctrl_get_iface_node (hicn_face_id_t face_id)
{
- if (dpo->dpoi_type == hicn_face_ip_type)
- {
- switch (dpo->dpoi_proto)
- {
- case DPO_PROTO_IP4:
- return HICN_MAPME_CTRL_NEXT_IP4_OUTPUT;
- case DPO_PROTO_IP6:
- return HICN_MAPME_CTRL_NEXT_IP6_OUTPUT;
- default:
- return HICN_MAPME_CTRL_NEXT_ERROR_DROP;
- }
- }
- else if (dpo->dpoi_type == hicn_face_udp_type)
- {
- switch (dpo->dpoi_proto)
- {
- case DPO_PROTO_IP4:
- return HICN_MAPME_CTRL_NEXT_UDP46_OUTPUT;
- case DPO_PROTO_IP6:
- return HICN_MAPME_CTRL_NEXT_UDP66_OUTPUT;
- default:
- return HICN_MAPME_CTRL_NEXT_ERROR_DROP;
- }
- }
- else
+ hicn_face_t * face = hicn_dpoi_get_from_idx(face_id);
+
+ switch (face->dpo.dpoi_proto)
{
+ case DPO_PROTO_IP4:
+ return HICN_MAPME_CTRL_NEXT_IP4_OUTPUT;
+ case DPO_PROTO_IP6:
+ return HICN_MAPME_CTRL_NEXT_IP6_OUTPUT;
+ default:
return HICN_MAPME_CTRL_NEXT_ERROR_DROP;
}
}
diff --git a/hicn-plugin/src/mapme_ctrl_node.c b/hicn-plugin/src/mapme_ctrl_node.c
index ed25a31b0..a0be2be1d 100644
--- a/hicn-plugin/src/mapme_ctrl_node.c
+++ b/hicn-plugin/src/mapme_ctrl_node.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -48,18 +48,6 @@ static char *hicn_mapme_ctrl_error_strings[] = {
#undef _
};
-/**
- * Preprocess the ingress face so as to make it a candidate next hop, which is
- * what MAP-Me will handle
- */
-static_always_inline void
-preprocess_in_face (hicn_type_t type, dpo_id_t * in, dpo_id_t * out)
-{
- u32 vlib_edge = hicn_mapme_get_dpo_vlib_edge (in);
- *out = *in;
- out->dpoi_next_node = vlib_edge;
-}
-
/*
* @brief Process incoming control messages (Interest Update)
* @param vm vlib main data structure
@@ -74,7 +62,7 @@ preprocess_in_face (hicn_type_t type, dpo_id_t * in, dpo_id_t * out)
*/
static_always_inline bool
hicn_mapme_process_ctrl (vlib_main_t * vm, vlib_buffer_t * b,
- dpo_id_t * in_face)
+ hicn_face_id_t in_face_id)
{
seq_t fib_seq;
const dpo_id_t *dpo;
@@ -153,25 +141,26 @@ hicn_mapme_process_ctrl (vlib_main_t * vm, vlib_buffer_t * b,
// in_face and next_hops are face_id_t
/* Remove ingress face from TFIB in case it was present */
- hicn_mapme_tfib_del (tfib, in_face);
+ hicn_mapme_tfib_del (tfib, in_face_id);
/* Move next hops to TFIB... but in_face... */
for (u8 pos = 0; pos < tfib->entry_count; pos++)
{
- if (dpo_cmp (&tfib->next_hops[pos], in_face) == 0)
- {
- tfib->entry_count = 0;
- break;
- }
+ hicn_face_t * face = hicn_dpoi_get_from_idx(tfib->next_hops[pos]);
+ hicn_face_t * in_face = hicn_dpoi_get_from_idx(in_face_id);
+ if (dpo_is_adj(&face->dpo))
+ {
+ ip_adjacency_t * adj = adj_get (dpo->dpoi_index);
+ if (ip46_address_cmp(&(adj->sub_type.nbr.next_hop), &(in_face->nat_addr))== 0)
+ break;
+ }
DEBUG
("Adding nexthop to the tfib, dpo index in_face %d, dpo index tfib %d",
- in_face->dpoi_index, tfib->next_hops[pos].dpoi_index);
- hicn_mapme_tfib_add (tfib, &tfib->next_hops[pos]);
+ in_face_id, tfib->next_hops[pos]);
+ hicn_mapme_tfib_add (tfib, tfib->next_hops[pos]);
}
- /* ... and set ingress face as next_hop */
- in_face->dpoi_next_node = hicn_mapme_get_dpo_vlib_edge (in_face);
- hicn_mapme_nh_set (tfib, in_face);
+ hicn_mapme_nh_set (tfib, in_face_id);
/* We transmit both the prefix and the full dpo (type will be needed to pick the right transmit node */
retx_t *retx = vlib_process_signal_event_data (vm,
@@ -181,8 +170,10 @@ hicn_mapme_process_ctrl (vlib_main_t * vm, vlib_buffer_t * b,
1,
sizeof (retx_t));
*retx = (retx_t)
- {
- .prefix = prefix,.dpo = *dpo};
+ {
+ .prefix = prefix,
+ .dpo = *dpo
+ };
}
else if (params.seq == fib_seq)
@@ -191,10 +182,10 @@ hicn_mapme_process_ctrl (vlib_main_t * vm, vlib_buffer_t * b,
params.seq, fib_seq);
/* Remove ingress face from TFIB in case it was present */
- hicn_mapme_tfib_del (tfib, in_face);
+ hicn_mapme_tfib_del (tfib, in_face_id);
/* Add ingress face to next hops */
- hicn_mapme_nh_add (tfib, in_face);
+ hicn_mapme_nh_add (tfib, in_face_id);
/* Multipath, multihoming, multiple producers or duplicate interest */
retx_t *retx = vlib_process_signal_event_data (vm,
@@ -204,8 +195,10 @@ hicn_mapme_process_ctrl (vlib_main_t * vm, vlib_buffer_t * b,
1,
sizeof (retx_t));
*retx = (retx_t)
- {
- .prefix = prefix,.dpo = *dpo};
+ {
+ .prefix = prefix,
+ .dpo = *dpo
+ };
}
else // params.seq < fib_seq
{
@@ -213,7 +206,7 @@ hicn_mapme_process_ctrl (vlib_main_t * vm, vlib_buffer_t * b,
* face is propagating outdated information, we can just consider it as a
* prevHops
*/
- hicn_mapme_tfib_add (tfib, in_face);
+ hicn_mapme_tfib_add (tfib, in_face_id);
retx_t *retx = vlib_process_signal_event_data (vm,
hicn_mapme_eventmgr_process_node.
@@ -222,8 +215,10 @@ hicn_mapme_process_ctrl (vlib_main_t * vm, vlib_buffer_t * b,
1,
sizeof (retx_t));
*retx = (retx_t)
- {
- .prefix = prefix,.dpo = *dpo};
+ {
+ .prefix = prefix,
+ .dpo = *dpo
+ };
}
/* We just raise events, the event_mgr is in charge of forging packet. */
@@ -245,7 +240,7 @@ hicn_mapme_ctrl_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
hicn_mapme_ctrl_next_t next_index;
u32 n_left_from, *from, *to_next;
n_left_from = frame->n_vectors;
- dpo_id_t in_face;
+ //hicn_face_id_t in_face;
from = vlib_frame_vector_args (frame);
n_left_from = frame->n_vectors;
@@ -273,16 +268,11 @@ hicn_mapme_ctrl_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
hb = hicn_get_buffer (b0);
/* This determines the next node on which the ack will be sent back */
- u32 next0 = hicn_mapme_get_dpo_iface_node (&hb->face_dpo_id);
+ u32 next0 = hicn_mapme_ctrl_get_iface_node (hb->face_id);
- /* Preprocessing is needed to precompute in the dpo the next node
- * that will have to be followed by regular interests when being
- * forwarder on a given next hop
- */
- preprocess_in_face (hb->type, &hb->face_dpo_id, &in_face);
- hicn_mapme_process_ctrl (vm, b0, &in_face);
+ hicn_mapme_process_ctrl (vm, b0, hb->face_id);
- vnet_buffer (b0)->ip.adj_index[VLIB_TX] = in_face.dpoi_index;
+ vnet_buffer (b0)->ip.adj_index[VLIB_TX] = hb->face_id;
vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
n_left_to_next, bi0, next0);
@@ -331,10 +321,8 @@ VLIB_REGISTER_NODE (hicn_mapme_ctrl_node) =
* Manager. This node is only responsible for sending ACK back,
* Acks are like data packets are output on iface's
*/
- [HICN_MAPME_CTRL_NEXT_IP4_OUTPUT] = "hicn-iface-ip4-output",
- [HICN_MAPME_CTRL_NEXT_IP6_OUTPUT] = "hicn-iface-ip6-output",
- [HICN_MAPME_CTRL_NEXT_UDP46_OUTPUT] = "hicn-iface-udp4-output",
- [HICN_MAPME_CTRL_NEXT_UDP66_OUTPUT] = "hicn-iface-udp6-output",
+ [HICN_MAPME_CTRL_NEXT_IP4_OUTPUT] = "hicn4-iface-output",
+ [HICN_MAPME_CTRL_NEXT_IP6_OUTPUT] = "hicn6-iface-output",
[HICN_MAPME_CTRL_NEXT_ERROR_DROP] = "error-drop",
},
};
diff --git a/hicn-plugin/src/mapme_eventmgr.c b/hicn-plugin/src/mapme_eventmgr.c
index 5a9e7967e..d8b7562f8 100644
--- a/hicn-plugin/src/mapme_eventmgr.c
+++ b/hicn-plugin/src/mapme_eventmgr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -71,7 +71,7 @@ ip6_fib_table_show_walk (fib_node_index_t fib_entry_index, void *arg)
}
void
-hicn_mapme_process_fib_entry (vlib_main_t * vm, dpo_id_t face,
+hicn_mapme_process_fib_entry (vlib_main_t * vm, hicn_face_id_t face,
const fib_node_index_t * fib_entry_index)
{
const dpo_id_t *load_balance_dpo_id;
@@ -103,7 +103,7 @@ hicn_mapme_process_fib_entry (vlib_main_t * vm, dpo_id_t face,
}
void
-hicn_mapme_process_ip4_fib (vlib_main_t * vm, dpo_id_t face)
+hicn_mapme_process_ip4_fib (vlib_main_t * vm, hicn_face_id_t face)
{
ip4_main_t *im4 = &ip4_main;
fib_table_t *fib_table;
@@ -138,7 +138,7 @@ hicn_mapme_process_ip4_fib (vlib_main_t * vm, dpo_id_t face)
}
void
-hicn_mapme_process_ip6_fib (vlib_main_t * vm, dpo_id_t face)
+hicn_mapme_process_ip6_fib (vlib_main_t * vm, hicn_face_id_t face)
{
/* Walk IPv6 FIB */
ip6_main_t *im6 = &ip6_main;
@@ -182,7 +182,7 @@ hicn_mapme_process_ip6_fib (vlib_main_t * vm, dpo_id_t face)
* Callback called everytime a new face is created (not including app faces)
*/
void
-hicn_mapme_on_face_added (vlib_main_t * vm, dpo_id_t face)
+hicn_mapme_on_face_added (vlib_main_t * vm, hicn_face_id_t face)
{
hicn_mapme_process_ip4_fib (vm, face);
hicn_mapme_process_ip6_fib (vm, face);
@@ -242,7 +242,7 @@ get_packet_buffer (vlib_main_t * vm, u32 node_index, u32 dpoi_index,
static_always_inline bool
hicn_mapme_send_message (vlib_main_t * vm, const hicn_prefix_t * prefix,
- mapme_params_t * params, dpo_id_t * face)
+ mapme_params_t * params, hicn_face_id_t face)
{
size_t n;
@@ -261,7 +261,7 @@ hicn_mapme_send_message (vlib_main_t * vm, const hicn_prefix_t * prefix,
vlib_node_t *node = vlib_get_node_by_name (vm, (u8 *) node_name);
u32 node_index = node->index;
- u8 *buffer = get_packet_buffer (vm, node_index, face->dpoi_index,
+ u8 *buffer = get_packet_buffer (vm, node_index, face,
(ip46_address_t *) prefix,
(params->protocol ==
IPPROTO_IPV6) ? HICN_TYPE_IPV6_ICMP :
@@ -302,13 +302,13 @@ hicn_mapme_send_updates (vlib_main_t * vm, hicn_prefix_t * prefix,
pos++)
{
hicn_mapme_send_message (vm, prefix, &params,
- &tfib->next_hops[pos]);
+ tfib->next_hops[pos]);
}
}
else
{
hicn_mapme_send_message (vm, prefix, &params,
- &tfib->next_hops[tfib_last_idx]);
+ tfib->next_hops[tfib_last_idx]);
}
}
@@ -372,7 +372,7 @@ hicn_mapme_eventmgr_process (vlib_main_t * vm,
retx_t *retx_events = event_data;
for (u8 i = 0; i < vec_len (retx_events); i++)
{
- hicn_mapme_on_face_added (vm, retx_events[i].dpo);
+ hicn_mapme_on_face_added (vm, retx_events[i].face_id);
}
idle = 0;
}
diff --git a/hicn-plugin/src/mapme_eventmgr.h b/hicn-plugin/src/mapme_eventmgr.h
index 338915d63..b63d16805 100644
--- a/hicn-plugin/src/mapme_eventmgr.h
+++ b/hicn-plugin/src/mapme_eventmgr.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -15,6 +15,13 @@
#include <vlib/vlib.h> // vlib_node_registration_t (vlib/node.h)
+#include <hicn/name.h>
+
+/**
+ * @file mapme_eventmgr.h
+ *
+ */
+
/*
* Structure carrying all necessary information for managing Special Interest
* (re)transmissions.
@@ -23,6 +30,7 @@ typedef struct
{
hicn_prefix_t prefix;
dpo_id_t dpo;
+ hicn_face_id_t face_id;
u8 rtx_count; // Number of retransmissions since last tfib addition
} retx_t;
diff --git a/hicn-plugin/src/mgmt.h b/hicn-plugin/src/mgmt.h
index 326922a01..6db0fe0c1 100644
--- a/hicn-plugin/src/mgmt.h
+++ b/hicn-plugin/src/mgmt.h
@@ -20,6 +20,11 @@
#include "faces/face.h"
#include "hicn_api.h"
+/**
+ * @file mgmt.h
+ *
+ */
+
typedef struct icn_stats_s
{
u32 pkts_processed;
diff --git a/hicn-plugin/src/params.h b/hicn-plugin/src/params.h
index 606d42992..606d50771 100644
--- a/hicn-plugin/src/params.h
+++ b/hicn-plugin/src/params.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -18,6 +18,12 @@
#include <math.h>
+/**
+ * @file params.h
+ *
+ */
+
+
/*
* Features
*/
@@ -37,7 +43,7 @@ STATIC_ASSERT ((HICN_PARAM_FACES_MAX & (HICN_PARAM_FACES_MAX - 1)) == 0,
#define HICN_PARAM_HICN_NAME_LEN_MAX 20 //bytes
// Max next - hops supported in a FIB entry
-#define HICN_PARAM_FIB_ENTRY_NHOPS_MAX 5
+#define HICN_PARAM_FIB_ENTRY_NHOPS_MAX 10
// Default and limit on weight, whatever weight means
#define HICN_PARAM_FIB_ENTRY_NHOP_WGHT_DFLT 0x10
diff --git a/hicn-plugin/src/parser.h b/hicn-plugin/src/parser.h
index 0d72780ae..e79d65831 100644
--- a/hicn-plugin/src/parser.h
+++ b/hicn-plugin/src/parser.h
@@ -21,6 +21,9 @@
#include "hicn.h"
#include "error.h"
+/**
+ * @file parser.h
+ */
/*
* Key type codes for header, header tlvs, body tlvs, and child tlvs
@@ -33,6 +36,15 @@ enum hicn_pkt_type_e
HICN_PKT_TYPE_CONTENT = 1,
};
+/**
+ * @brief Parse an 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
+ */
always_inline int
hicn_interest_parse_pkt (vlib_buffer_t * pkt, hicn_name_t * name,
u16 * namelen, hicn_header_t ** pkt_hdrp, u8 * isv6)
@@ -61,6 +73,15 @@ hicn_interest_parse_pkt (vlib_buffer_t * pkt, hicn_name_t * name,
return HICN_ERROR_NONE;
}
+/**
+ * @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
+ */
always_inline int
hicn_data_parse_pkt (vlib_buffer_t * pkt, hicn_name_t * name,
u16 * namelen, hicn_header_t ** pkt_hdrp, u8 * isv6)
diff --git a/hicn-plugin/src/pcs.c b/hicn-plugin/src/pcs.c
index 4355aaeb0..6c44b9d83 100644
--- a/hicn-plugin/src/pcs.c
+++ b/hicn-plugin/src/pcs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -34,7 +34,6 @@ hicn_pit_create (hicn_pit_cs_t * p, u32 num_elems)
(HICN_PARAM_CS_LRU_DEFAULT * HICN_PARAM_CS_RESERVED_APP / 100);
p->policy_state.count = 0;
p->policy_state.head = p->policy_state.tail = 0;
- p->pcs_app_max = HICN_PARAM_CS_LRU_DEFAULT - p->policy_state.max;
p->policy_vft.hicn_cs_insert = hicn_cs_lru.hicn_cs_insert;
p->policy_vft.hicn_cs_update = hicn_cs_lru.hicn_cs_update;
diff --git a/hicn-plugin/src/pcs.h b/hicn-plugin/src/pcs.h
index fc63bd0a6..a9e1ae5a0 100644
--- a/hicn-plugin/src/pcs.h
+++ b/hicn-plugin/src/pcs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -22,8 +22,17 @@
#include "error.h"
#include "cache_policies/cs_policy.h"
#include "faces/face.h"
-#include "faces/ip/dpo_ip.h"
-#include "faces/app/face_prod.h"
+
+/**
+ * @file pcs.h
+ *
+ * This file implement the PIT and CS which are collapsed in the same
+ * structure, thereore an entry is either a PIT entry of a CS entry.
+ * The implementation consist of a hash table where each entry of the
+ * hash table contains a PIT or CS entry, some counters to maintain the
+ * status of the PIT/CS and the reference to the eviction policy for
+ * the CS. The default eviction policy id FIFO.
+ */
/* The PIT and CS are stored as a union */
#define HICN_PIT_NULL_TYPE 0
@@ -32,7 +41,7 @@
/*
* Definitions and Forward refs for the time counters we're trying out.
- * Counters are maintained by the background process.
+ * Counters are maintained by the background process. TODO.
*/
#define SEC_MS 1000
#define HICN_INFRA_FAST_TIMER_SECS 1
@@ -41,8 +50,7 @@
#define HICN_INFRA_SLOW_TIMER_MSECS (HICN_INFRA_SLOW_TIMER_SECS * SEC_MS)
/*
- * Max number of incoming (interest) faces supported, for now. Note that
- * changing this may change alignment within the PIT struct, so be careful.
+ * Note that changing this may change alignment within the PIT struct, so be careful.
*/
typedef struct __attribute__ ((packed)) hicn_pcs_shared_s
{
@@ -72,48 +80,41 @@ typedef struct __attribute__ ((packed)) hicn_pit_entry_s
/*
* Egress next hop (containes the egress face) This id refers to the
- * nh
- */
- /* choosen in the next_hops array of the dpo */
+ * position of the choosen face in the next_hops array of the dpo */
/* 18B + 1B = 19B */
u8 pe_txnh;
- /* Array of faces */
+ /* Array of incoming ifaces */
/* 24B + 32B (8B*4) =56B */
hicn_face_db_t faces;
} hicn_pit_entry_t;
-#define HICN_CS_ENTRY_OPAQUE_SIZE HICN_HASH_NODE_APP_DATA_SIZE - 40
+#define HICN_CS_ENTRY_OPAQUE_SIZE HICN_HASH_NODE_APP_DATA_SIZE - 36
/*
* CS entry, unioned with a PIT entry below
*/
typedef struct __attribute__ ((packed)) hicn_cs_entry_s
{
- /* 22B + 2B = 24B */
+ /* 18B + 2B = 20B */
u16 align;
/* Packet buffer, if held */
- /* 18B + 4B = 22B */
+ /* 20B + 4B = 24B */
u32 cs_pkt_buf;
/* Ingress face */
- /* 24B + 8B = 32B */
- //Fix alignment issues
- union
- {
- dpo_id_t cs_rxface;
- u64 cs_rxface_u64;
- };
+ /* 24B + 4B = 28B */
+ hicn_face_id_t cs_rxface;
/* Linkage for LRU, in the form of hashtable node indexes */
- /* 32B + 8B = 40B */
+ /* 28B + 8B = 36B */
u32 cs_lru_prev;
u32 cs_lru_next;
/* Reserved for implementing cache policy different than LRU */
- /* 40B + (64 - 40)B = 64B */
+ /* 36B + (64 - 36)B = 64B */
u8 opaque[HICN_CS_ENTRY_OPAQUE_SIZE];
@@ -154,10 +155,6 @@ typedef struct hicn_pit_cs_s
/* Total size of PCS */
u32 pcs_size;
- /* Memory reserved for appfaces */
- u32 pcs_app_max;
- u32 pcs_app_count;
-
hicn_cs_policy_t policy_state;
hicn_cs_policy_vft_t policy_vft;
@@ -170,7 +167,7 @@ always_inline void
hicn_pit_to_cs (vlib_main_t * vm, hicn_pit_cs_t * pitcs,
hicn_pcs_entry_t * pcs_entry, hicn_hash_entry_t * hash_entry,
hicn_hash_node_t * node, const hicn_dpo_vft_t * dpo_vft,
- dpo_id_t * hicn_dpo_id, dpo_id_t * inface_id, u8 is_appface);
+ dpo_id_t * hicn_dpo_id, hicn_face_id_t inface_id, u8 is_appface);
always_inline void
hicn_pcs_cs_update (vlib_main_t * vm, hicn_pit_cs_t * pitcs,
@@ -197,7 +194,7 @@ hicn_pcs_cs_insert_update (vlib_main_t * vm, hicn_pit_cs_t * pitcs,
hicn_hash_entry_t ** hash_entry, u64 hashval,
u32 * node_id, index_t * dpo_ctx_id, u8 * vft_id,
u8 * is_cs, u8 * hash_entry_id, u32 * bucket_id,
- u8 * bucket_is_overflow, dpo_id_t * inface);
+ u8 * bucket_is_overflow, hicn_face_id_t inface);
always_inline int
hicn_pcs_pit_insert (hicn_pit_cs_t * pitcs, hicn_pcs_entry_t * entry,
@@ -285,16 +282,6 @@ hicn_pit_set_lru_max (hicn_pit_cs_t * p, u32 limit)
}
/*
- * Configure CS LRU limit. Zero is accepted, means 'no limit', probably not a
- * good choice.
- */
-static inline void
-hicn_pit_set_lru_app_max (hicn_pit_cs_t * p, u32 limit)
-{
- p->pcs_app_max = limit;
-}
-
-/*
* Accessor for PIT interest counter.
*/
static inline u32
@@ -385,7 +372,7 @@ always_inline void
hicn_pit_to_cs (vlib_main_t * vm, hicn_pit_cs_t * pitcs,
hicn_pcs_entry_t * pcs_entry, hicn_hash_entry_t * hash_entry,
hicn_hash_node_t * node, const hicn_dpo_vft_t * dpo_vft,
- dpo_id_t * hicn_dpo_id, dpo_id_t * inface_id, u8 is_appface)
+ dpo_id_t * hicn_dpo_id, hicn_face_id_t inface_id, u8 is_appface)
{
/*
@@ -401,25 +388,14 @@ hicn_pit_to_cs (vlib_main_t * vm, hicn_pit_cs_t * pitcs,
node->hn_flags |= HICN_HASH_NODE_CS_FLAGS;
pcs_entry->shared.entry_flags |= HICN_PCS_ENTRY_CS_FLAG;
- pcs_entry->u.cs.cs_rxface = *inface_id;
+ pcs_entry->u.cs.cs_rxface = inface_id;
/* Update the CS according to the policy */
hicn_cs_policy_t *policy_state;
hicn_cs_policy_vft_t *policy_vft;
- if (is_appface)
- {
- dpo_id_t *face_dpo = (dpo_id_t *) & (pcs_entry->u.cs.cs_rxface);
- hicn_face_t *face = hicn_dpoi_get_from_idx (face_dpo->dpoi_index);
- hicn_face_prod_t *prod_face = (hicn_face_prod_t *) face->data;
- policy_state = &prod_face->policy;
- policy_vft = &prod_face->policy_vft;
- }
- else
- {
- policy_state = &pitcs->policy_state;
- policy_vft = &pitcs->policy_vft;
- }
+ policy_state = &pitcs->policy_state;
+ policy_vft = &pitcs->policy_vft;
policy_vft->hicn_cs_insert (pitcs, node, pcs_entry, policy_state);
pitcs->pcs_cs_count++;
@@ -456,42 +432,18 @@ hicn_pcs_cs_update (vlib_main_t * vm, hicn_pit_cs_t * pitcs,
hicn_cs_policy_t *policy_state;
hicn_cs_policy_vft_t *policy_vft;
- dpo_id_t *face_dpo = (dpo_id_t *) & (old_entry->u.cs.cs_rxface);
policy_state = &pitcs->policy_state;
policy_vft = &pitcs->policy_vft;
- if (face_dpo->dpoi_type == hicn_face_ip_type)
- {
- hicn_face_t *face = hicn_dpoi_get_from_idx (face_dpo->dpoi_index);
- if (face->shared.flags & HICN_FACE_FLAGS_APPFACE_PROD)
- {
- hicn_face_prod_t *prod_face = (hicn_face_prod_t *) face->data;
- policy_state = &prod_face->policy;
- policy_vft = &prod_face->policy_vft;
- }
- }
-
- if (dpo_cmp (&entry->u.cs.cs_rxface, &old_entry->u.cs.cs_rxface) != 0)
+ if (entry->u.cs.cs_rxface != old_entry->u.cs.cs_rxface)
{
/* Dequeue content from the old queue */
policy_vft->hicn_cs_dequeue (pitcs, node, old_entry, policy_state);
- dpo_copy (&old_entry->u.cs.cs_rxface, &entry->u.cs.cs_rxface);
- face_dpo = (dpo_id_t *) & (old_entry->u.cs.cs_rxface);
+ old_entry->u.cs.cs_rxface = entry->u.cs.cs_rxface;
policy_state = &pitcs->policy_state;
policy_vft = &pitcs->policy_vft;
- if (face_dpo->dpoi_type == hicn_face_ip_type)
- {
- hicn_face_t *face = hicn_dpoi_get_from_idx (face_dpo->dpoi_index);
- if (face->shared.flags & HICN_FACE_FLAGS_APPFACE_PROD)
- {
- hicn_face_prod_t *prod_face = (hicn_face_prod_t *) face->data;
- policy_state = &prod_face->policy;
- policy_vft = &prod_face->policy_vft;
- }
- }
-
policy_vft->hicn_cs_insert (pitcs, node, old_entry, policy_state);
if (policy_state->count > policy_state->max)
@@ -530,20 +482,9 @@ hicn_pcs_cs_delete (vlib_main_t * vm, hicn_pit_cs_t * pitcs,
hicn_cs_policy_t *policy_state;
hicn_cs_policy_vft_t *policy_vft;
- dpo_id_t *face_dpo = (dpo_id_t *) & ((*pcs_entryp)->u.cs.cs_rxface);
policy_state = &pitcs->policy_state;
policy_vft = &pitcs->policy_vft;
- if (face_dpo->dpoi_type == hicn_face_ip_type)
- {
- hicn_face_t *face = hicn_dpoi_get_from_idx (face_dpo->dpoi_index);
- if (face->shared.flags & HICN_FACE_FLAGS_APPFACE_PROD)
- {
- hicn_face_prod_t *prod_face = (hicn_face_prod_t *) face->data;
- policy_state = &prod_face->policy;
- policy_vft = &prod_face->policy_vft;
- }
- }
policy_vft->hicn_cs_dequeue (pitcs, (*nodep), (*pcs_entryp),
policy_state);
@@ -589,20 +530,9 @@ hicn_pcs_cs_insert (vlib_main_t * vm, hicn_pit_cs_t * pitcs,
hicn_cs_policy_t *policy_state;
hicn_cs_policy_vft_t *policy_vft;
- dpo_id_t *face_dpo = (dpo_id_t *) & (entry->u.cs.cs_rxface);
policy_state = &pitcs->policy_state;
policy_vft = &pitcs->policy_vft;
- if (face_dpo->dpoi_type == hicn_face_ip_type)
- {
- hicn_face_t *face = hicn_dpoi_get_from_idx (face_dpo->dpoi_index);
- if (face->shared.flags & HICN_FACE_FLAGS_APPFACE_PROD)
- {
- hicn_face_prod_t *prod_face = (hicn_face_prod_t *) face->data;
- policy_state = &prod_face->policy;
- policy_vft = &prod_face->policy_vft;
- }
- }
policy_vft->hicn_cs_insert (pitcs, node, entry, policy_state);
pitcs->pcs_cs_count++;
@@ -639,13 +569,13 @@ hicn_pcs_cs_insert_update (vlib_main_t * vm, hicn_pit_cs_t * pitcs,
hicn_hash_entry_t ** hash_entry, u64 hashval,
u32 * node_id, index_t * dpo_ctx_id, u8 * vft_id,
u8 * is_cs, u8 * hash_entry_id, u32 * bucket_id,
- u8 * bucket_is_overflow, dpo_id_t * inface)
+ u8 * bucket_is_overflow, hicn_face_id_t inface)
{
int ret;
ASSERT (entry == hicn_hashtb_node_data (node));
- entry->u.cs.cs_rxface = *inface;
+ entry->u.cs.cs_rxface = inface;
ret =
hicn_pcs_cs_insert (vm, pitcs, entry, node, hash_entry, hashval, node_id,
dpo_ctx_id, vft_id, is_cs, hash_entry_id, bucket_id,
diff --git a/hicn-plugin/src/pg.h b/hicn-plugin/src/pg.h
index 9ec3eeabc..84a391d43 100644
--- a/hicn-plugin/src/pg.h
+++ b/hicn-plugin/src/pg.h
@@ -18,7 +18,7 @@
/**
- * @File Packet generator for hICN
+ * @file pg.h
*
* The packet generator is made of two entities, a client and a server.
* The client issues interests at high speed and the server satisfy each
diff --git a/hicn-plugin/src/route.c b/hicn-plugin/src/route.c
index c208dd4c1..3b774cd82 100644
--- a/hicn-plugin/src/route.c
+++ b/hicn-plugin/src/route.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -15,9 +15,14 @@
#include <vnet/fib/fib_entry.h>
#include <vnet/fib/fib_table.h>
+#include <vnet/fib/fib_entry_track.h>
#include <vnet/ip/ip6_packet.h>
+#include <vnet/ip/ip.h>
#include <vnet/dpo/dpo.h>
+#include <vnet/dpo/drop_dpo.h>
#include <vnet/dpo/load_balance.h>
+#include <vnet/udp/udp.h>
+#include <vnet/udp/udp_encap.h>
#include <vlib/global_funcs.h>
#include "strategy_dpo_ctx.h"
@@ -26,11 +31,18 @@
#include "faces/face.h"
#include "error.h"
#include "strategies/dpo_mw.h"
+#include "infra.h"
+#include "udp_tunnels/udp_tunnel.h"
#define FIB_SOURCE_HICN 0x04 //Right after the FIB_SOURCE_INTERFACE priority
fib_source_t hicn_fib_src;
+fib_node_type_t hicn_fib_node_type;
+
+ip4_address_t localhost4 = {0};
+ip6_address_t localhost6 = {0};
+
int
hicn_route_get_dpo (const fib_prefix_t * prefix,
const dpo_id_t ** hicn_dpo, u32 * fib_index)
@@ -91,134 +103,321 @@ hicn_route_get_dpo (const fib_prefix_t * prefix,
}
int
-hicn_route_add_nhops (hicn_face_id_t * face_id, u32 len,
- const fib_prefix_t * prefix)
+hicn_route_set_strategy (fib_prefix_t * prefix, u8 strategy_id)
{
const dpo_id_t *hicn_dpo_id;
- int ret = HICN_ERROR_NONE;
- dpo_id_t faces_dpo_tmp[HICN_PARAM_FIB_ENTRY_NHOPS_MAX];
- int n_face_dpo = 0;
- const hicn_dpo_vft_t *dpo_vft;
+ dpo_id_t new_dpo_id = DPO_INVALID;
+ int ret;
+ hicn_dpo_ctx_t *old_hicn_dpo_ctx;
+ const hicn_dpo_vft_t *new_dpo_vft;
+ index_t new_hicn_dpo_idx;
u32 fib_index;
- vlib_main_t *vm = vlib_get_main ();
- hicn_face_vft_t *face_vft = NULL;
- if (face_id == NULL)
+ ret = hicn_route_get_dpo (prefix, &hicn_dpo_id, &fib_index);
+
+ if (ret == HICN_ERROR_NONE)
{
- return HICN_ERROR_ROUTE_INVAL;
+ old_hicn_dpo_ctx = hicn_strategy_dpo_ctx_get (hicn_dpo_id->dpoi_index);
+
+ new_dpo_vft = hicn_dpo_get_vft_from_id (strategy_id);
+
+ if (new_dpo_vft == NULL || old_hicn_dpo_ctx == NULL)
+ return HICN_ERROR_STRATEGY_NOT_FOUND;
+
+ /* Create a new dpo for the new strategy */
+ new_dpo_vft->hicn_dpo_create (hicn_dpo_id->dpoi_proto,
+ old_hicn_dpo_ctx->next_hops,
+ old_hicn_dpo_ctx->entry_count,
+ &new_hicn_dpo_idx);
+
+ /* the value we got when we registered */
+ dpo_set (&new_dpo_id,
+ new_dpo_vft->hicn_dpo_get_type (),
+ (ip46_address_is_ip4 (&prefix->fp_addr) ? DPO_PROTO_IP4 :
+ DPO_PROTO_IP6), new_hicn_dpo_idx);
+
+ /* Here is where we create the "via" like route */
+ /*
+ * For the moment we use the global one the prefix you want
+ * to match Neale suggested -- FIB_SOURCE_HICN the client
+ * that is adding them -- no easy explanation at this time…
+ */
+ fib_node_index_t new_fib_node_index =
+ fib_table_entry_special_dpo_update (fib_index,
+ prefix,
+ hicn_fib_src,
+ FIB_ENTRY_FLAG_EXCLUSIVE,
+ &new_dpo_id);
+
+ dpo_unlock (&new_dpo_id);
+ ret =
+ (new_fib_node_index !=
+ FIB_NODE_INDEX_INVALID) ? HICN_ERROR_NONE :
+ HICN_ERROR_ROUTE_NOT_UPDATED;
}
- /*
- * Check is the faces are available, otherwise skip the face
- * id_adjacency existance is not checked. It should be checked before
- * sending a packet out
- */
- for (int i = 0; i < clib_min (HICN_PARAM_FIB_ENTRY_NHOPS_MAX, len); i++)
+ //Remember to remove the lock from the table when removing the entry
+ return ret;
+
+}
+
+int
+ip_nh_add_helper (fib_protocol_t fib_proto, const fib_prefix_t * rpfx, ip46_address_t * nh, u32 sw_if)
+{
+ fib_route_path_t *rpaths = NULL, rpath;
+
+ u32 fib_index = fib_table_find(fib_proto, 0);
+
+ clib_memset(&rpath, 0, sizeof(rpath));
+ rpath.frp_weight = 1;
+ rpath.frp_sw_if_index = sw_if;
+ rpath.frp_addr = *nh;
+ rpath.frp_proto = ip46_address_is_ip4(nh) ? DPO_PROTO_IP4 : DPO_PROTO_IP6;
+
+ vec_add1(rpaths, rpath);
+
+ fib_table_entry_path_add2 (fib_index,
+ rpfx,
+ FIB_SOURCE_CLI,
+ FIB_ENTRY_FLAG_NONE, rpaths);
+ return 0;
+}
+
+int
+ip_nh_del_helper (fib_protocol_t fib_proto, const fib_prefix_t * rpfx, ip46_address_t * nh, u32 sw_if)
+{
+ fib_route_path_t *rpaths = NULL, rpath;
+
+ u32 fib_index = fib_table_find(fib_proto, 0);
+
+ clib_memset(&rpath, 0, sizeof(rpath));
+ rpath.frp_weight = 1;
+ rpath.frp_sw_if_index = sw_if;
+ rpath.frp_addr = *nh;
+ rpath.frp_proto = ip46_address_is_ip4(nh) ? DPO_PROTO_IP4 : DPO_PROTO_IP6;
+
+ vec_add1(rpaths, rpath);
+
+ fib_table_entry_path_remove2 (fib_index,
+ rpfx,
+ FIB_SOURCE_CLI,
+ rpaths);
+ return 0;
+}
+
+
+static ip46_address_t * get_address(ip46_address_t * nh, u32 sw_if, fib_protocol_t proto)
+{
+ ip46_address_t * local_address = calloc(1, sizeof(ip46_address_t));
+
+ if (proto == FIB_PROTOCOL_IP4)
{
- hicn_face_t *face = hicn_dpoi_get_from_idx (face_id[i]);
- face_vft = hicn_face_get_vft (face->shared.face_type);
- dpo_id_t face_dpo = DPO_INVALID;
- face_vft->hicn_face_get_dpo (face, &face_dpo);
+ ip_interface_address_t *interface_address;
+ ip4_address_t *addr =
+ ip4_interface_address_matching_destination (&ip4_main,
+ &nh->ip4,
+ sw_if,
+ &interface_address);
+
+ if (addr == NULL)
+ addr = ip4_interface_first_address (&ip4_main,
+ sw_if,
+ &interface_address);
+ if (addr != NULL)
+ ip46_address_set_ip4 (local_address, addr);
+ }
+ else if (proto == FIB_PROTOCOL_IP6)
+ {
+ ip_interface_address_t *interface_address;
+ ip6_interface_address_matching_destination (&ip6_main,
+ &nh->ip6,
+ sw_if,
+ &interface_address);
+
+ ip6_address_t *addr = NULL;
+ if (interface_address != NULL)
+ addr =
+ (ip6_address_t *)
+ ip_interface_address_get_address (&ip6_main.lookup_main,
+ interface_address);
+
+ if (addr == NULL)
+ addr = ip6_interface_first_address (&ip6_main, sw_if);
+
+ if (addr != NULL)
+ ip46_address_set_ip6 (local_address, addr);
+ }
- if (!dpo_id_is_valid (&face_dpo))
- {
- vlib_cli_output (vm, "Face %d not found, skip...\n", face_id[i]);
- return ret;
- }
+ return local_address;
+}
+
+static void
+sync_hicn_fib_entry(hicn_dpo_ctx_t *fib_entry)
+{
+ const dpo_id_t * dpo_loadbalance = fib_entry_contribute_ip_forwarding (fib_entry->fib_entry_index);
+ const load_balance_t *lb0 = load_balance_get(dpo_loadbalance->dpoi_index);
+ index_t hicn_fib_entry_index = hicn_strategy_dpo_ctx_get_index(fib_entry);
+ hicn_face_id_t * vec_faces = 0;
+
+ dpo_id_t temp = DPO_INVALID;
+ const dpo_id_t *former_dpo = &temp;
+ int index = 0;
+ for (int j = 0; j < lb0->lb_n_buckets; j++) {
+ const dpo_id_t * dpo = load_balance_get_bucket_i(lb0,j);
+
+ int dpo_comparison = dpo_cmp(former_dpo, dpo);
+ former_dpo = dpo;
+ /*
+ * Loadbalancing in ip replicate the dpo in multiple buckets
+ * in order to honor the assigned weights.
+ */
+ if (dpo_comparison == 0)
+ continue;
+
+ u32 sw_if = ~0;
+ ip46_address_t * nh = NULL;
+ hicn_face_id_t face_id = HICN_FACE_NULL;
+
+ if (dpo_is_adj(dpo))
+ {
+ ip_adjacency_t * adj = adj_get (dpo->dpoi_index);
+ sw_if = adj->rewrite_header.sw_if_index;
+ nh = get_address (&(adj->sub_type.nbr.next_hop), sw_if, fib_entry->proto);
+ }
+ else if (dpo->dpoi_type == dpo_type_udp_ip4 || dpo->dpoi_type == dpo_type_udp_ip6)
+ {
+ u8 proto = dpo->dpoi_type == dpo_type_udp_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6;
+ nh = calloc (1, sizeof(ip46_address_t));
+ switch (dpo->dpoi_proto)
+ {
+ case FIB_PROTOCOL_IP6:
+ nh = calloc (1, sizeof(ip46_address_t));
+ ip46_address_set_ip6(nh, &localhost6);
+ break;
+ case FIB_PROTOCOL_IP4:
+ nh = calloc (1, sizeof(ip46_address_t));
+ ip46_address_set_ip4(nh, &localhost4);
+ break;
+ default:
+ nh = calloc (1, sizeof(ip46_address_t));
+ }
+ udp_tunnel_add_existing (dpo->dpoi_index, proto);
+ }
+ else //if (dpo_is_drop(dpo))
+ {
+ sw_if = dpo_get_urpf(dpo);
+ nh = calloc (1, sizeof(ip46_address_t));
+ }
+
+ /* Careful, this adds a lock on the face if it exists */
+ hicn_face_add(dpo, nh, sw_if, &face_id, 0);
+
+ vec_validate(vec_faces, index);
+ vec_faces[index] = face_id;
+ index++;
+
+ /* Face creation can realloc load_balance_t? Seem the fib_tracking does so. */
+ dpo_loadbalance = fib_entry_contribute_ip_forwarding (fib_entry->fib_entry_index);
+ lb0 = load_balance_get(dpo_loadbalance->dpoi_index);
+ }
+
+ const hicn_dpo_vft_t * strategy_vft = hicn_dpo_get_vft(fib_entry->dpo_type);
+ int i = 0;
+ while (i < fib_entry->entry_count)
+ {
+ u32 idx_nh = vec_search(vec_faces, fib_entry->next_hops[i]);
+ if (idx_nh == ~0)
+ {
+ strategy_vft->hicn_dpo_del_nh(fib_entry->next_hops[i], hicn_fib_entry_index);
+ }
else
- {
- faces_dpo_tmp[n_face_dpo++] = face_dpo;
- }
- }
+ {
+ vec_del1(vec_faces, idx_nh);
- ret = hicn_route_get_dpo (prefix, &hicn_dpo_id, &fib_index);
+ /* Remove the lock added by hicn_face_add */
+ hicn_face_unlock_with_id (fib_entry->next_hops[i]);
+ i++;
+ }
+ }
- if (ret == HICN_ERROR_NONE)
+ hicn_face_id_t *face_id;
+ vec_foreach(face_id, vec_faces)
{
- for (int i = 0; i < n_face_dpo && (ret == HICN_ERROR_NONE); i++)
- {
- u32 vft_id = hicn_dpo_get_vft_id (hicn_dpo_id);
- dpo_vft = hicn_dpo_get_vft (vft_id);
-
- hicn_face_t *face =
- hicn_dpoi_get_from_idx (faces_dpo_tmp[i].dpoi_index);
- //Disable feature on the interface
- if (prefix->fp_proto == FIB_PROTOCOL_IP4)
- vnet_feature_enable_disable ("ip4-local", "hicn-data-input-ip4",
- face->shared.sw_if, 1, 0, 0);
- else if (prefix->fp_proto == FIB_PROTOCOL_IP6)
- vnet_feature_enable_disable ("ip6-local", "hicn-data-input-ip6",
- face->shared.sw_if, 1, 0, 0);
-
- ret = dpo_vft->hicn_dpo_add_update_nh (&faces_dpo_tmp[i],
- hicn_dpo_id->dpoi_index);
- }
+ strategy_vft->hicn_dpo_add_update_nh(*face_id, hicn_fib_entry_index);
+
+ /* Remove the lock added by hicn_face_add */
+ hicn_face_unlock_with_id (*face_id);
+
}
- return ret;
+ vec_free(vec_faces);
}
-/* Add a new route for a name prefix */
-int
-hicn_route_add (hicn_face_id_t * face_id, u32 len,
- const fib_prefix_t * prefix)
+static void
+enable_disable_data_receiving (fib_protocol_t proto, u32 sw_if, u8 is_enable)
{
- dpo_id_t dpo = DPO_INVALID;
- const dpo_id_t *hicn_dpo_id;
- int ret = HICN_ERROR_NONE;
- dpo_id_t face_dpo_tmp[HICN_PARAM_FIB_ENTRY_NHOPS_MAX];
- int n_face_dpo = 0;
- index_t dpo_idx;
- u32 fib_index;
- vlib_main_t *vm = vlib_get_main ();
- hicn_face_vft_t *face_vft = NULL;
+ if (proto == FIB_PROTOCOL_IP4 && sw_if != ~0)
+ vnet_feature_enable_disable ("ip4-local", "hicn-data-input-ip4",
+ sw_if, is_enable, 0, 0);
+ else if (proto == FIB_PROTOCOL_IP6 && sw_if != ~0)
+ vnet_feature_enable_disable ("ip6-local", "hicn-data-input-ip6",
+ sw_if, is_enable, 0, 0);
- if (face_id == NULL || !hicn_dpoi_idx_is_valid (*face_id))
- {
- return HICN_ERROR_ROUTE_INVAL;
+}
+
+walk_rc_t enable_data_receiving_new_fib_entry (vnet_main_t * vnm,
+ vnet_sw_interface_t * si,
+ void *ctx)
+{
+ fib_protocol_t *proto = (fib_protocol_t *) ctx;
+ enable_disable_data_receiving(*proto, si->sw_if_index, 1);
+
+ return (WALK_CONTINUE);
+}
+
+walk_rc_t disable_data_receiving_rm_fib_entry (vnet_main_t * vnm,
+ vnet_sw_interface_t * si,
+ void *ctx)
+{
+ fib_protocol_t *proto = (fib_protocol_t *) ctx;
+ enable_disable_data_receiving(*proto, si->sw_if_index, 0);
+
+ return (WALK_CONTINUE);
}
+
+int
+hicn_route_enable (fib_prefix_t *prefix) {
+
+ int ret = HICN_ERROR_NONE;
+ fib_node_index_t fib_entry_index;
+
+ /* Check if the route already exist in the fib */
/*
- * Check is the faces are available, otherwise skip the face
- * id_adjacency existance is not checked. It should be checked before
- * sending a packet out
+ * ASSUMPTION: we use table 0 which is the default table and it is
+ * already existing and locked
*/
- for (int i = 0; i < clib_min (HICN_PARAM_FIB_ENTRY_NHOPS_MAX, len); i++)
+ u32 fib_index = fib_table_find(prefix->fp_proto, 0);
+
+ fib_entry_index = fib_table_lookup_exact_match (fib_index, prefix);
+
+ if (fib_entry_index == FIB_NODE_INDEX_INVALID)
{
- hicn_face_t *face = hicn_dpoi_get_from_idx (face_id[i]);
- face_vft = hicn_face_get_vft (face->shared.face_type);
- dpo_id_t face_dpo = DPO_INVALID;
- face_vft->hicn_face_get_dpo (face, &face_dpo);
+ fib_entry_index = fib_table_lookup (fib_index, prefix);
- if (!dpo_id_is_valid (&face_dpo))
- {
- vlib_cli_output (vm, "Face %d not found, skip...\n", face_id[i]);
- return ret;
- }
- else
- {
- face_dpo_tmp[n_face_dpo++] = face_dpo;
- }
+ fib_route_path_t * paths = fib_entry_encode(fib_entry_index);
+
+ fib_table_entry_path_add2(fib_index, prefix, FIB_SOURCE_CLI, FIB_ENTRY_FLAG_NONE, paths);
}
- ret = hicn_route_get_dpo (prefix, &hicn_dpo_id, &fib_index);
+ /* Check if the prefix is already enabled */
+ u32 fib_hicn_index = fib_table_find(prefix->fp_proto, HICN_FIB_TABLE);
- if (ret == HICN_ERROR_ROUTE_NOT_FOUND)
- {
- dpo_id_t nhops[HICN_PARAM_FIB_ENTRY_NHOPS_MAX];
- for (int i = 0; i < n_face_dpo; i++)
- {
- clib_memcpy (&nhops[i], &face_dpo_tmp[i], sizeof (dpo_id_t));
- hicn_face_t *face =
- hicn_dpoi_get_from_idx (face_dpo_tmp[i].dpoi_index);
- //Disable feature on the interface
- if (prefix->fp_proto == FIB_PROTOCOL_IP4)
- vnet_feature_enable_disable ("ip4-local", "hicn-data-input-ip4",
- face->shared.sw_if, 1, 0, 0);
- else if (prefix->fp_proto == FIB_PROTOCOL_IP6)
- vnet_feature_enable_disable ("ip6-local", "hicn-data-input-ip6",
- face->shared.sw_if, 1, 0, 0);
- }
+ fib_node_index_t fib_hicn_entry_index = fib_table_lookup_exact_match (fib_hicn_index, prefix);
- default_dpo.hicn_dpo_create (prefix->fp_proto, nhops, n_face_dpo,
- &dpo_idx);
+ if (fib_hicn_entry_index == FIB_NODE_INDEX_INVALID)
+ {
+ dpo_id_t dpo = DPO_INVALID;
+ index_t dpo_idx;
+ default_dpo.hicn_dpo_create (prefix->fp_proto, 0, NEXT_HOP_INVALID,
+ &dpo_idx);
/* the value we got when we registered */
/*
@@ -226,9 +425,20 @@ hicn_route_add (hicn_face_id_t * face_id, u32 len,
* object
*/
dpo_set (&dpo,
- default_dpo.hicn_dpo_get_type (),
- (ip46_address_is_ip4 (&prefix->fp_addr) ? DPO_PROTO_IP4 :
- DPO_PROTO_IP6), dpo_idx);
+ default_dpo.hicn_dpo_get_type (),
+ (ip46_address_is_ip4 (&prefix->fp_addr) ? DPO_PROTO_IP4 :
+ DPO_PROTO_IP6), dpo_idx);
+
+ hicn_dpo_ctx_t * fib_entry = hicn_strategy_dpo_ctx_get(dpo_idx);
+
+ fib_node_init (&fib_entry->fib_node, hicn_fib_node_type);
+ fib_node_lock (&fib_entry->fib_node);
+
+ fib_entry->fib_entry_index = fib_entry_track (fib_index,
+ prefix,
+ hicn_fib_node_type,
+ dpo_idx, &fib_entry->fib_sibling);
+
/* Here is where we create the "via" like route */
/*
@@ -236,163 +446,317 @@ hicn_route_add (hicn_face_id_t * face_id, u32 len,
* to match Neale suggested -- FIB_SOURCE_HICN the client
* that is adding them -- no easy explanation at this time…
*/
- 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),
- &dpo);
+ CLIB_UNUSED (fib_node_index_t new_fib_node_index) =
+ fib_table_entry_special_dpo_add (fib_hicn_index,
+ prefix,
+ hicn_fib_src,
+ (FIB_ENTRY_FLAG_EXCLUSIVE |
+ FIB_ENTRY_FLAG_LOOSE_URPF_EXEMPT),
+ &dpo);
+
+ sync_hicn_fib_entry(fib_entry);
/* We added a route, therefore add one lock to the table */
fib_table_lock (fib_index, prefix->fp_proto, hicn_fib_src);
- dpo_unlock (&dpo);
- ret =
- (new_fib_node_index !=
- FIB_NODE_INDEX_INVALID) ? HICN_ERROR_NONE :
- HICN_ERROR_ROUTE_NO_INSERT;
-
- /*
- * TODO: we might want to store the fib index in the face.
- * This will help to update the fib entries when a face is
- * deleted. Fib_index_t is returned from
- * fib_table_entry_special_dpo_add.
+ /* Enable the feature to punt data packet every time we enable a new hicn route
+ * For each enable there must be a disable to defenitely disable the feature
+ *
+ * We cannot enable only the interfaces on which we send out interest because
+ * Data packet might be coming on in different interfaces, as in che case of mpls
+ * tunnels (packets are received from the physical nic, not the mpls tunnel interface).
*/
+ vnet_main_t * vnm = vnet_get_main ();
+ vnet_sw_interface_walk(vnm, enable_data_receiving_new_fib_entry, &(prefix->fp_proto));
+
+ dpo_unlock (&dpo);
}
- else if (ret == HICN_ERROR_NONE)
+ else
{
- ret = hicn_route_add_nhops (face_id, len, prefix);
+ const dpo_id_t *load_balance_dpo_id;
+ const dpo_id_t *strategy_dpo_id;
+
+ /* Route already existing. We need to update the dpo. */
+ load_balance_dpo_id =
+ fib_entry_contribute_ip_forwarding (fib_hicn_entry_index);
+
+ /* The dpo is not a load balance dpo as expected */
+ if (load_balance_dpo_id->dpoi_type != DPO_LOAD_BALANCE)
+ {
+ ret = HICN_ERROR_ROUTE_NO_LD;
+ goto done;
+ }
+ else
+ {
+ load_balance_t *lb =
+ load_balance_get (load_balance_dpo_id->dpoi_index);
+
+ strategy_dpo_id = load_balance_get_bucket_i (lb, 0);
+
+ if (!dpo_is_hicn (strategy_dpo_id))
+ {
+ ret = HICN_ERROR_ROUTE_DPO_NO_HICN;
+ goto done;
+ }
+
+ if (lb->lb_n_buckets > 1)
+ {
+ ret = HICN_ERROR_ROUTE_MLT_LD;
+ goto done;
+ }
+
+ hicn_dpo_ctx_t * hicn_fib_entry = hicn_strategy_dpo_ctx_get(strategy_dpo_id->dpoi_index);
+
+ sync_hicn_fib_entry(hicn_fib_entry);
+ }
}
+
+ done:
return ret;
}
int
-hicn_route_del (fib_prefix_t * prefix)
-{
- const dpo_id_t *hicn_dpo_id;
+hicn_route_disable (fib_prefix_t *prefix) {
+
int ret = HICN_ERROR_NONE;
- u32 fib_index;
- /* Remove the fib entry only if the dpo is of type hicn */
- ret = hicn_route_get_dpo (prefix, &hicn_dpo_id, &fib_index);
+ /* Check if the prefix is already enabled */
+ u32 fib_hicn_index = fib_table_find(prefix->fp_proto, HICN_FIB_TABLE);
- if (ret == HICN_ERROR_NONE)
+ fib_node_index_t fib_hicn_entry_index = fib_table_lookup_exact_match (fib_hicn_index, prefix);
+
+ if (fib_hicn_entry_index == FIB_NODE_INDEX_INVALID)
{
- fib_table_entry_special_remove (HICN_FIB_TABLE, prefix, hicn_fib_src);
+ return HICN_ERROR_ROUTE_NOT_FOUND;
+ }
+ else
+ {
+ const dpo_id_t *load_balance_dpo_id;
+ const dpo_id_t *strategy_dpo_id;
+ hicn_dpo_ctx_t * hicn_fib_entry;
- /*
- * Remove the lock from the table. We keep one lock per route
- */
- fib_table_unlock (fib_index, prefix->fp_proto, hicn_fib_src);
+ /* Route already existing. We need to update the dpo. */
+ load_balance_dpo_id =
+ fib_entry_contribute_ip_forwarding (fib_hicn_entry_index);
+
+ /* The dpo is not a load balance dpo as expected */
+ if (load_balance_dpo_id->dpoi_type != DPO_LOAD_BALANCE)
+ {
+ ret = HICN_ERROR_ROUTE_NO_LD;
+ goto done;
+ }
+ else
+ {
+ load_balance_t *lb =
+ load_balance_get (load_balance_dpo_id->dpoi_index);
+
+ strategy_dpo_id = load_balance_get_bucket_i (lb, 0);
+
+ if (!dpo_is_hicn (strategy_dpo_id))
+ {
+ ret = HICN_ERROR_ROUTE_DPO_NO_HICN;
+ goto done;
+ }
+
+ if (lb->lb_n_buckets > 1)
+ {
+ ret = HICN_ERROR_ROUTE_MLT_LD;
+ goto done;
+ }
+
+ hicn_fib_entry = hicn_strategy_dpo_ctx_get(strategy_dpo_id->dpoi_index);
+
+ for (int i = 0; i < hicn_fib_entry->entry_count; i++)
+ {
+ hicn_strategy_dpo_ctx_del_nh(hicn_fib_entry->next_hops[i], hicn_fib_entry);
+ }
+ }
+
+ fib_entry_untrack(hicn_fib_entry->fib_entry_index, hicn_fib_entry->fib_sibling);
+
+ fib_table_entry_special_remove (fib_hicn_index, prefix, hicn_fib_src);
+
+ /* Disable the feature to punt data packet every time we enable a new hicn route */
+ vnet_main_t * vnm = vnet_get_main ();
+ vnet_sw_interface_walk(vnm, disable_data_receiving_rm_fib_entry, &(prefix->fp_proto));
}
- //Remember to remove the lock from the table when removing the entry
+
+ done:
return ret;
}
-int
-hicn_route_del_nhop (fib_prefix_t * prefix, hicn_face_id_t face_id)
+
+static fib_node_t *
+hicn_ctx_node_get (fib_node_index_t index)
{
- const dpo_id_t *hicn_dpo_id;
- int ret;
- u32 vft_id;
- const hicn_dpo_vft_t *dpo_vft;
- u32 fib_index;
+ hicn_dpo_ctx_t * hicn_ctx;
+ hicn_ctx = hicn_strategy_dpo_ctx_get(index);
- ret = hicn_route_get_dpo (prefix, &hicn_dpo_id, &fib_index);
+ return (&hicn_ctx->fib_node);
+}
- /* Check if the dpo is an hicn_dpo_t */
- if (ret == HICN_ERROR_NONE)
- {
- vft_id = hicn_dpo_get_vft_id (hicn_dpo_id);
- dpo_vft = hicn_dpo_get_vft (vft_id);
+static void
+hicn_fib_last_lock_gone (fib_node_t *node)
+{
+}
- hicn_face_t *face = hicn_dpoi_get_from_idx (face_id);
- //Disable feature on the interface
- if (prefix->fp_proto == FIB_PROTOCOL_IP4)
- vnet_feature_enable_disable ("ip4-local", "hicn-data-input-ip4",
- face->shared.sw_if, 0, 0, 0);
- else if (prefix->fp_proto == FIB_PROTOCOL_IP6)
- vnet_feature_enable_disable ("ip6-local", "hicn-data-input-ip6",
- face->shared.sw_if, 0, 0, 0);
+static hicn_dpo_ctx_t *
+hicn_ctx_from_fib_node (fib_node_t * node)
+{
+ return ((hicn_dpo_ctx_t *) (((char *) node) -
+ STRUCT_OFFSET_OF (hicn_dpo_ctx_t, fib_node)));
+}
- ret = dpo_vft->hicn_dpo_del_nh (face_id, hicn_dpo_id->dpoi_index);
+static fib_node_back_walk_rc_t
+hicn_fib_back_walk_notify (fib_node_t *node,
+ fib_node_back_walk_ctx_t *ctx)
+{
- hicn_dpo_ctx_t *dpo_ctx =
- hicn_strategy_dpo_ctx_get (hicn_dpo_id->dpoi_index);
+ hicn_dpo_ctx_t *fib_entry = hicn_ctx_from_fib_node (node);
+ sync_hicn_fib_entry(fib_entry);
- if (ret == HICN_ERROR_NONE && !dpo_ctx->entry_count)
- ret = hicn_route_del (prefix);
- }
- //Remember to remove the lock from the table when removing the entry
- return ret;
+ return (FIB_NODE_BACK_WALK_CONTINUE);
}
-int
-hicn_route_set_strategy (fib_prefix_t * prefix, u8 strategy_id)
+static void
+hicn_fib_show_memory (void)
{
- const dpo_id_t *hicn_dpo_id;
- dpo_id_t new_dpo_id = DPO_INVALID;
- int ret;
- hicn_dpo_ctx_t *old_hicn_dpo_ctx;
- const hicn_dpo_vft_t *new_dpo_vft;
- index_t new_hicn_dpo_idx;
- u32 fib_index;
+}
- ret = hicn_route_get_dpo (prefix, &hicn_dpo_id, &fib_index);
- if (ret == HICN_ERROR_NONE)
+static const fib_node_vft_t hicn_fib_vft =
+{
+ .fnv_get = hicn_ctx_node_get,
+ .fnv_last_lock = hicn_fib_last_lock_gone,
+ .fnv_back_walk = hicn_fib_back_walk_notify,
+ .fnv_mem_show = hicn_fib_show_memory,
+};
+
+fib_table_walk_rc_t enable_data_on_existing_hicn(fib_node_index_t fei,
+ void *ctx)
+{
+ u32 sw_if = *(u32 *)ctx;
+ const dpo_id_t *load_balance_dpo_id;
+ const dpo_id_t *strategy_dpo_id;
+
+ /* Route already existing. We need to update the dpo. */
+ load_balance_dpo_id =
+ fib_entry_contribute_ip_forwarding (fei);
+
+ /* The dpo is not a load balance dpo as expected */
+ if (load_balance_dpo_id->dpoi_type != DPO_LOAD_BALANCE)
{
- old_hicn_dpo_ctx = hicn_strategy_dpo_ctx_get (hicn_dpo_id->dpoi_index);
+ goto done;
+ }
+ else
+ {
+ load_balance_t *lb =
+ load_balance_get (load_balance_dpo_id->dpoi_index);
- new_dpo_vft = hicn_dpo_get_vft_from_id (strategy_id);
+ strategy_dpo_id = load_balance_get_bucket_i (lb, 0);
- if (new_dpo_vft == NULL || old_hicn_dpo_ctx == NULL)
- return HICN_ERROR_STRATEGY_NOT_FOUND;
+ if (!dpo_is_hicn (strategy_dpo_id))
+ {
+ goto done;
+ }
- /* Create a new dpo for the new strategy */
- new_dpo_vft->hicn_dpo_create (hicn_dpo_id->dpoi_proto,
- old_hicn_dpo_ctx->next_hops,
- old_hicn_dpo_ctx->entry_count,
- &new_hicn_dpo_idx);
+ enable_disable_data_receiving (strategy_dpo_id->dpoi_proto, sw_if, 1);
+ }
- /* the value we got when we registered */
- dpo_set (&new_dpo_id,
- new_dpo_vft->hicn_dpo_get_type (),
- (ip46_address_is_ip4 (&prefix->fp_addr) ? DPO_PROTO_IP4 :
- DPO_PROTO_IP6), new_hicn_dpo_idx);
+ done:
+ return (FIB_TABLE_WALK_CONTINUE);
+}
- /* Here is where we create the "via" like route */
+static clib_error_t *
+set_table_interface_add_del (vnet_main_t * vnm, u32 sw_if_index, u32 is_add)
+{
+
+ if (!is_add)
+ return HICN_ERROR_NONE;
+
+ vnet_sw_interface_t * sw_int = vnet_get_sw_interface(vnm, sw_if_index);
+ vnet_hw_interface_t * hw_int = vnet_get_hw_interface(vnm, sw_int->hw_if_index);
+
+ char * mpls = "mpls";
+ if (strstr((char *)hw_int->name, mpls) == NULL)
+ return 0;
+
+ int rv = ip_table_bind (FIB_PROTOCOL_IP4, sw_if_index, HICN_FIB_TABLE, 1);
+
+ if (!rv)
+ {
+ rv = ip_table_bind (FIB_PROTOCOL_IP6, sw_if_index, HICN_FIB_TABLE, 1);
+
+ if (rv)
+ {
+ /* An error occurred. Bind the interface back to the default fib */
+ ip_table_bind (FIB_PROTOCOL_IP4, sw_if_index, 0, 1);
+ }
+ }
+
+ u32 fib_index = fib_table_find(FIB_PROTOCOL_IP4,
+ HICN_FIB_TABLE);
+ if (fib_index != ~0)
+ {
/*
- * For the moment we use the global one the prefix you want
- * to match Neale suggested -- FIB_SOURCE_HICN the client
- * that is adding them -- no easy explanation at this time…
+ * Walk the ip4 and ip6 fib tables to discover existing hicn fib entries.
+ * For each of them we need to enable the feature to punt data packets.
*/
- fib_node_index_t new_fib_node_index =
- fib_table_entry_special_dpo_update (fib_index,
- prefix,
- hicn_fib_src,
- FIB_ENTRY_FLAG_EXCLUSIVE,
- &new_dpo_id);
+ fib_table_walk(fib_index,
+ FIB_PROTOCOL_IP4,
+ enable_data_on_existing_hicn,
+ &sw_if_index);
+ }
- dpo_unlock (&new_dpo_id);
- ret =
- (new_fib_node_index !=
- FIB_NODE_INDEX_INVALID) ? HICN_ERROR_NONE :
- HICN_ERROR_ROUTE_NOT_UPDATED;
+ fib_index = fib_table_find(FIB_PROTOCOL_IP6,
+ HICN_FIB_TABLE);
+ if (fib_index != ~0)
+ {
+ fib_table_walk(fib_index,
+ FIB_PROTOCOL_IP6,
+ enable_data_on_existing_hicn,
+ &sw_if_index);
}
- //Remember to remove the lock from the table when removing the entry
- return ret;
+ return rv ? clib_error_return (0, "unable to add hicn table to interface") : 0;
}
+VNET_SW_INTERFACE_ADD_DEL_FUNCTION (set_table_interface_add_del);
+
void
hicn_route_init ()
{
+ vnet_main_t * vnm = vnet_get_main ();
+ vlib_main_t * vm = vlib_get_main ();
hicn_fib_src = fib_source_allocate ("hicn",
FIB_SOURCE_HICN, FIB_SOURCE_BH_API);
+
+ hicn_fib_node_type = fib_node_register_new_type(&hicn_fib_vft);
+
+ ip_table_create(FIB_PROTOCOL_IP4, HICN_FIB_TABLE, 1, (const u8 *)"hicn4");
+ ip_table_create(FIB_PROTOCOL_IP6, HICN_FIB_TABLE, 1, (const u8 *)"hicn6");
+
+ u32 sw_if_index;
+ u8 mac_address[6];
+ u8 is_specified = 0;
+ u32 user_instance = 0;
+
+ vnet_create_loopback_interface (&sw_if_index, mac_address,
+ is_specified, user_instance);
+
+ localhost4.as_u8[0] = 127;
+ localhost4.as_u8[3] = 1;
+ u32 length4 = 32, length6 = 128, is_del = 0, flags = 0;
+
+ localhost6.as_u8[15] = 1;
+
+ ip4_add_del_interface_address (vm, sw_if_index, &localhost4, length4, is_del);
+ ip6_add_del_interface_address (vm, sw_if_index, &localhost6, length6, is_del);
+
+ flags |= VNET_SW_INTERFACE_FLAG_ADMIN_UP;
+ vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
}
/*
diff --git a/hicn-plugin/src/route.h b/hicn-plugin/src/route.h
index 5877f31a8..a1ba86b3d 100644
--- a/hicn-plugin/src/route.h
+++ b/hicn-plugin/src/route.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -21,36 +21,102 @@
#include "hicn.h"
#include "faces/face.h"
+/**
+ * @file route.h
+ *
+ * hICN uses a specific vrf to install the routes for a prefix has been enabled to
+ * be hicn. It considers the vrf 0 (the default vrf) as the dominating vrf on
+ * which every route is stored. Enabling a prefix to be hICN will copy all the routes
+ * in the vrf 0 for the given prefi, in the vrf HICN. Every modification made on the
+ * vrf 0 on an hICN enabled prefix is reflected in the vrf hICN (through the use of
+ * the fib entry tracking functionality). Moreover, we use the lookup in the vrf hICN
+ * as a way for punting packet that must be processed as hICN. The implementation will
+ * install a special dpo as a single next hop for the vpp load balancer for each entry
+ * in the vrf hICN that we enabled. Such dpo will have two purposes: 1) to punt packets
+ * to the hICN forwarding pipeline, 2) to point to the righe strategy (the dpoi_index will
+ * be an index to the strategy context while the dpoi_type will be an index to the strategy vft).
+ *
+ * Additionally, hICN assign each interface to the vrf hICN; this is required for
+ * the interest lookup. Vpp performs a lookup in the vrf assigned to the interface,
+ * therefore if an interface is not assigned to the hICN vrf, the lookup will be done
+ * on the vrf 0 and the packet won't be processed through the hicn forwarding pipeline.
+ */
+
/*
- * Retrieve the hicn dpo corresponding to a hicn prefix
+ * Adding each interface to the vrf hICN has the side effect that to ping you need to
+ * specify the vrf hICN in the command.
+ */
+
+extern fib_source_t hicn_fib_src;
+
+extern dpo_type_t udp_encap_dpo_types[FIB_PROTOCOL_MAX];
+
+/**
+ * @Brief Return the hicn_dpo corresponding to the prefix in teh vrf HICN
+ *
+ * @param prefix Prefix for which we want to retrieve the hICN dpo
+ * @param hicn_dpo return value with the hicn_dpo
+ * @param fib_index return value with the fib index corresponding to the prefix
*/
int
hicn_route_get_dpo (const fib_prefix_t * prefix,
const dpo_id_t ** hicn_dpo, u32 * fib_index);
-/*
- * Add a new route for a name prefix
+
+/**
+ * @Brief Set the strategy for a given prefix
+ *
+ * @param prefix Prefix for which we set the strategy
+ * @param stretegy_id Index of the strategy to set
*/
int
-hicn_route_add (hicn_face_id_t * face_id, u32 len,
- const fib_prefix_t * prefix);
+hicn_route_set_strategy (fib_prefix_t * prefix, u32 strategy_id);
-/*
- * Add new next hops for a prefix route
+/**
+ * @Brief Helper to add a nex hop in the vrf 0. If there are no entries in the
+ * vrf 0 that matches with the prefix (epm), a new one is created.
+ *
+ * @param fib_proto FIB_PROTOCOL_IP6 or FIB_PROTOCOL_IP4 (mpls not supported)
+ * @param pfx Prefix for which to add a next hop
+ * @param nh Next hop to add
+ * @param sw_if Software interface index to add in the next hop
*/
int
-hicn_route_add_nhops (hicn_face_id_t * face_id, u32 len,
- const fib_prefix_t * prefix);
+ip_nh_add_helper (fib_protocol_t fib_proto, const fib_prefix_t * pfx, ip46_address_t * nh, u32 sw_if);
-/* Remove a route for a name prefix */
-int hicn_route_del (fib_prefix_t * prefix);
+/**
+ * @Brief Helper to remove a nex hop in the vrf 0. If there are no entries in the
+ * vrf 0 nothing happens.
+ *
+ * @param fib_proto FIB_PROTOCOL_IP6 or FIB_PROTOCOL_IP4 (mpls not supported)
+ * @param pfx Prefix for which to remove a next hop
+ * @param nh Next hop to remove
+ * @param sw_if Software interface index in the next hop definition
+ */
+int
+ip_nh_del_helper (fib_protocol_t fib_proto, const fib_prefix_t * rpfx, ip46_address_t * nh, u32 sw_if);
-/* Remove a next hop route for a name prefix */
-int hicn_route_del_nhop (fib_prefix_t * prefix, u32 face_id);
+/**
+ * @Brief Enable an hICN for an ip prefix
+ *
+ * @param prefix Prefix for which we enable hICN
+ * @return HICN_ERROR_NONE if hICN was enabled on the prefix
+ * HICN_ERROR_ROUTE_NO_LD if the first dpo for the fib entry corresponding to the prefix is not a load_balancer
+ * HICN_ERROR_ROUTE_DPO_NO_HICN if the loadbalancer in the vrf HICN already contains a dpo which is not an hICN one
+ * HICN_ERROR_ROUTE_MLT_LD if there are more than a dpo in the vpp loadbalancer
+ */
+int
+hicn_route_enable (fib_prefix_t *prefix);
-/* Remove a next hop route for a name prefix */
+/**
+ * @Brief Disable an hICN for an ip prefix. If hICN wasn't enable on the prefix
+ * nothing happens and it returns HICN_ERROR_ROUTE_NOT_FOUND
+ *
+ * @param prefix Prefix for which we disable hICN
+ */
int
-hicn_route_set_strategy (fib_prefix_t * prefix, u32 strategy_id);
+hicn_route_disable (fib_prefix_t *prefix);
+
/* Init route internal strustures */
void
diff --git a/hicn-plugin/src/state.h b/hicn-plugin/src/state.h
index 7e984e6c3..37003d0ae 100644
--- a/hicn-plugin/src/state.h
+++ b/hicn-plugin/src/state.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -26,26 +26,26 @@
#include "strategy_dpo_ctx.h"
#include "strategy_dpo_manager.h"
-always_inline void
-hicn_prefetch_pcs_entry (hicn_buffer_t * hicnb, hicn_pit_cs_t * pitcs)
-{
- hicn_hash_node_t *node = pool_elt_at_index (pitcs->pcs_table->ht_nodes,
- hicnb->node_id);
-
- hicn_hash_bucket_t *bucket;
- if (hicnb->hash_bucket_flags & HICN_HASH_NODE_OVERFLOW_BUCKET)
- bucket =
- pool_elt_at_index (pitcs->pcs_table->ht_overflow_buckets,
- hicnb->bucket_id);
- else
- bucket =
- (hicn_hash_bucket_t *) (pitcs->pcs_table->ht_buckets +
- hicnb->bucket_id);
+/**
+ * @file plugin_state
+ *
+ * Helper functions to hicn state (hash node, hash entry, strategy vft, dpo vft and dpo context id)
+ *
+ */
- CLIB_PREFETCH (node, CLIB_CACHE_LINE_BYTES, STORE);
- CLIB_PREFETCH (bucket, CLIB_CACHE_LINE_BYTES, STORE);
-}
+//TODO exploit this state to prefetch hash nodes and entries.
+/**
+ * @brief Retrieve the hicn state
+ *
+ * @param hicnb hicn buffer used to retrieve the hicn state
+ * @param pitcs pointer to PIT/CS
+ * @param node node in the hash table referring to the buffer
+ * @param strategy_vft return value pointing to the strategy vft corresponding to the buffer
+ * @param dpo_vft return value pointing to the dpo vft corresponding to the buffer
+ * @param dpo_ctx_id return value pointing to the dpo context id corresponding to the buffer
+ * @param hash_entry entry in the hash table referring to the buffer
+ */
always_inline void
hicn_get_internal_state (hicn_buffer_t * hicnb, hicn_pit_cs_t * pitcs,
hicn_hash_node_t ** node,
@@ -77,6 +77,19 @@ hicn_get_internal_state (hicn_buffer_t * hicnb, hicn_pit_cs_t * pitcs,
* nodes can prefetch the corresponding state (PIT entry, dpo_ctx and the
* strategy vft
*/
+/**
+ * @brief Store the hicn state in the hicn buffer
+ *
+ * @param b vlib buffer holding the hICN packet
+ * @param name_hash hash of the hICN name
+ * @param node_id id of the node in the hash table referring to the buffer
+ * @param dpo_ctx_id id of the dpo context id corresponding to the buffer
+ * @param vft_id id of the strategy vft corresponding to the buffer
+ * @param hash_entry_id id of the entry in the hash table referring to the buffer
+ * @param bucket_id id of the hasth table bucket that holds the hash entry
+ * @param bucket_is_overflow 1 if the bucket is from the ht_overflow_buckets pool
+ * 0 if the bucket is from the ht_buckets pool
+ */
always_inline void
hicn_store_internal_state (vlib_buffer_t * b, u64 name_hash, u32 node_id,
u8 dpo_ctx_id, u8 vft_id, u8 hash_entry_id,
diff --git a/hicn-plugin/src/strategies/dpo_mw.c b/hicn-plugin/src/strategies/dpo_mw.c
index eebb572c4..12c77bce8 100644
--- a/hicn-plugin/src/strategies/dpo_mw.c
+++ b/hicn-plugin/src/strategies/dpo_mw.c
@@ -76,8 +76,6 @@ format_hicn_strategy_mw_ctx (u8 * s, va_list * ap)
index_t index = va_arg (*ap, index_t);
hicn_dpo_ctx_t *dpo_ctx = NULL;
hicn_strategy_mw_ctx_t *mw_dpo_ctx = NULL;
- dpo_id_t *next_hop = NULL;
- hicn_face_vft_t *face_vft = NULL;
u32 indent = va_arg (*ap, u32);;
dpo_ctx = hicn_strategy_dpo_ctx_get (index);
@@ -97,24 +95,20 @@ format_hicn_strategy_mw_ctx (u8 * s, va_list * ap)
buf = format (NULL, "TFIB");
else
continue;
- next_hop = &dpo_ctx->next_hops[i];
- face_vft = hicn_face_get_vft (next_hop->dpoi_type);
- if (face_vft != NULL)
- {
- s = format (s, "\n");
- s =
- format (s, "%U ", face_vft->format_face, next_hop->dpoi_index,
- indent);
- s = format (s, "weight %u", mw_dpo_ctx->weight[i]);
- s = format (s, " %s", buf);
- }
+
+ s = format (s, "\n");
+ s =
+ format (s, "%U ", format_hicn_face, dpo_ctx->next_hops[i],
+ indent);
+ s = format (s, "weight %u", mw_dpo_ctx->weight[i]);
+ s = format (s, " %s", buf);
}
return (s);
}
void
-hicn_strategy_mw_ctx_create (dpo_proto_t proto, const dpo_id_t * next_hop,
+hicn_strategy_mw_ctx_create (fib_protocol_t proto, const hicn_face_id_t * next_hop,
int nh_len, index_t * dpo_idx)
{
hicn_strategy_mw_ctx_t *hicn_strategy_mw_ctx;
@@ -126,13 +120,13 @@ hicn_strategy_mw_ctx_create (dpo_proto_t proto, const dpo_id_t * next_hop,
*dpo_idx = hicn_strategy_dpo_ctx_get_index (hicn_strategy_ctx);
- init_dpo_ctx (hicn_strategy_ctx, next_hop, nh_len, hicn_dpo_type_mw);
+ init_dpo_ctx (hicn_strategy_ctx, next_hop, nh_len, hicn_dpo_type_mw, proto);
memset (hicn_strategy_mw_ctx->weight, 0, HICN_PARAM_FIB_ENTRY_NHOPS_MAX);
}
int
-hicn_strategy_mw_ctx_add_nh (const dpo_id_t * nh, index_t dpo_idx)
+hicn_strategy_mw_ctx_add_nh (hicn_face_id_t nh, index_t dpo_idx)
{
hicn_dpo_ctx_t *hicn_strategy_dpo_ctx = hicn_strategy_dpo_ctx_get (dpo_idx);
u8 pos = 0;
diff --git a/hicn-plugin/src/strategies/dpo_mw.h b/hicn-plugin/src/strategies/dpo_mw.h
index ccc8d044f..433c415fb 100644
--- a/hicn-plugin/src/strategies/dpo_mw.h
+++ b/hicn-plugin/src/strategies/dpo_mw.h
@@ -19,6 +19,14 @@
#include <vnet/dpo/dpo.h>
#include "../strategy_dpo_ctx.h"
+/**
+ * @file dpo_mw.h
+ *
+ * This file implements the strategy vtf (see strategy.h) and
+ * the dpo vft (see strategy_dpo_manager.h) for the strategy
+ * maximum weight
+ */
+
#define DEFAULT_WEIGHT 0
typedef struct hicn_strategy_mw_ctx_s
@@ -60,7 +68,7 @@ hicn_dpo_ctx_t *hicn_strategy_mw_ctx_get (index_t index);
* @return HICN_ERROR_NONE if the creation was fine, otherwise EINVAL
*/
void
-hicn_strategy_mw_ctx_create (dpo_proto_t proto, const dpo_id_t * next_hop,
+hicn_strategy_mw_ctx_create (fib_protocol_t proto, const hicn_face_id_t * next_hop,
int nh_len, index_t * dpo_idx);
/**
@@ -75,7 +83,7 @@ hicn_strategy_mw_ctx_create (dpo_proto_t proto, const dpo_id_t * next_hop,
* @return HICN_ERROR_NONE if the update or insert was fine,
* otherwise HICN_ERROR_DPO_CTX_NOT_FOUND
*/
-int hicn_strategy_mw_ctx_add_nh (const dpo_id_t * nh, index_t dpo_idx);
+int hicn_strategy_mw_ctx_add_nh (hicn_face_id_t nh, index_t dpo_idx);
/**
* @brief Delete a next hop in the dpo ctx.
diff --git a/hicn-plugin/src/strategies/dpo_rr.c b/hicn-plugin/src/strategies/dpo_rr.c
index a67b06acb..adb7e1025 100644
--- a/hicn-plugin/src/strategies/dpo_rr.c
+++ b/hicn-plugin/src/strategies/dpo_rr.c
@@ -76,8 +76,6 @@ format_hicn_strategy_rr_ctx (u8 * s, va_list * ap)
index_t index = va_arg (*ap, index_t);
hicn_dpo_ctx_t *dpo_ctx = NULL;
hicn_strategy_rr_ctx_t *rr_dpo_ctx = NULL;
- dpo_id_t *next_hop = NULL;
- hicn_face_vft_t *face_vft = NULL;
u32 indent = va_arg (*ap, u32);
dpo_ctx = hicn_strategy_dpo_ctx_get (index);
@@ -88,7 +86,7 @@ format_hicn_strategy_rr_ctx (u8 * s, va_list * ap)
s =
format (s, "hicn-rr, next hop Face %d",
- dpo_ctx->next_hops[rr_dpo_ctx->current_nhop].dpoi_index);
+ dpo_ctx->next_hops[rr_dpo_ctx->current_nhop]);
for (i = 0; i < HICN_PARAM_FIB_ENTRY_NHOPS_MAX; i++)
{
@@ -101,23 +99,18 @@ format_hicn_strategy_rr_ctx (u8 * s, va_list * ap)
else
continue;
- next_hop = &dpo_ctx->next_hops[i];
- face_vft = hicn_face_get_vft (next_hop->dpoi_type);
- if (face_vft != NULL)
- {
- s = format (s, "\n");
- s =
- format (s, "%U ", face_vft->format_face, next_hop->dpoi_index,
- indent);
- s = format (s, " %s", buf);
- }
+ s = format (s, "\n");
+ s =
+ format (s, "%U ", format_hicn_face, dpo_ctx->next_hops[i],
+ indent);
+ s = format (s, " %s", buf);
}
return (s);
}
void
-hicn_strategy_rr_ctx_create (dpo_proto_t proto, const dpo_id_t * next_hop,
+hicn_strategy_rr_ctx_create (fib_protocol_t proto, const hicn_face_id_t * next_hop,
int nh_len, index_t * dpo_idx)
{
hicn_strategy_rr_ctx_t *hicn_strategy_rr_ctx;
@@ -129,13 +122,13 @@ hicn_strategy_rr_ctx_create (dpo_proto_t proto, const dpo_id_t * next_hop,
*dpo_idx = hicn_strategy_dpo_ctx_get_index (hicn_strategy_ctx);
- init_dpo_ctx (hicn_strategy_ctx, next_hop, nh_len, hicn_dpo_type_rr);
+ init_dpo_ctx (hicn_strategy_ctx, next_hop, nh_len, hicn_dpo_type_rr, proto);
hicn_strategy_rr_ctx->current_nhop = 0;
}
int
-hicn_strategy_rr_ctx_add_nh (const dpo_id_t * nh, index_t dpo_idx)
+hicn_strategy_rr_ctx_add_nh (hicn_face_id_t nh, index_t dpo_idx)
{
hicn_dpo_ctx_t *hicn_strategy_dpo_ctx = hicn_strategy_dpo_ctx_get (dpo_idx);
u8 pos = 0;
diff --git a/hicn-plugin/src/strategies/dpo_rr.h b/hicn-plugin/src/strategies/dpo_rr.h
index 8afd0dabc..e4e5b5372 100644
--- a/hicn-plugin/src/strategies/dpo_rr.h
+++ b/hicn-plugin/src/strategies/dpo_rr.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -20,6 +20,15 @@
#include "../strategy_dpo_ctx.h"
/**
+ * @file dpo_rr.h
+ *
+ * This file implements the strategy vtf (see strategy.h) and
+ * the dpo vft (see strategy_dpo_manager.h) for the strategy
+ * round robin.
+ */
+
+
+/**
* Context for the Round Robin strategy
*/
@@ -62,7 +71,7 @@ hicn_dpo_ctx_t *hicn_strategy_rr_ctx_get (index_t index);
* @return HICN_ERROR_NONE if the creation was fine, otherwise EINVAL
*/
void
-hicn_strategy_rr_ctx_create (dpo_proto_t proto, const dpo_id_t * next_hop,
+hicn_strategy_rr_ctx_create (fib_protocol_t proto, const hicn_face_id_t * next_hop,
int nh_len, index_t * dpo_idx);
/**
@@ -77,7 +86,7 @@ hicn_strategy_rr_ctx_create (dpo_proto_t proto, const dpo_id_t * next_hop,
* @return HICN_ERROR_NONE if the update or insert was fine,
* otherwise HICN_ERROR_DPO_CTX_NOT_FOUND
*/
-int hicn_strategy_rr_ctx_add_nh (const dpo_id_t * nh, index_t dpo_idx);
+int hicn_strategy_rr_ctx_add_nh (hicn_face_id_t nh, index_t dpo_idx);
/**
* @brief Delete a next hop in the dpo ctx.
diff --git a/hicn-plugin/src/strategies/strategy_mw.c b/hicn-plugin/src/strategies/strategy_mw.c
index 2422d4fed..fe4d5896a 100644
--- a/hicn-plugin/src/strategies/strategy_mw.c
+++ b/hicn-plugin/src/strategies/strategy_mw.c
@@ -25,7 +25,7 @@ void hicn_receive_data_mw (index_t dpo_idx, int nh_idx);
void hicn_add_interest_mw (index_t dpo_idx, hicn_hash_entry_t * pit_entry);
void hicn_on_interest_timeout_mw (index_t dpo_idx);
u32 hicn_select_next_hop_mw (index_t dpo_idx, int *nh_idx,
- dpo_id_t ** outface);
+ hicn_face_id_t* outface);
u32 get_strategy_node_index_mw (void);
u8 *hicn_strategy_format_trace_mw (u8 * s, hicn_strategy_trace_t * t);
u8 *hicn_strategy_format_mw (u8 * s, va_list * ap);
@@ -51,7 +51,7 @@ hicn_mw_strategy_get_vft (void)
/* DPO should be give in input as it containes all the information to calculate the next hops*/
u32
-hicn_select_next_hop_mw (index_t dpo_idx, int *nh_idx, dpo_id_t ** outface)
+hicn_select_next_hop_mw (index_t dpo_idx, int *nh_idx, hicn_face_id_t* outface)
{
hicn_dpo_ctx_t *dpo_ctx = hicn_strategy_dpo_ctx_get (dpo_idx);
@@ -64,20 +64,14 @@ hicn_select_next_hop_mw (index_t dpo_idx, int *nh_idx, dpo_id_t ** outface)
u8 next_hop_index = 0;
for (int i = 0; i < dpo_ctx->entry_count; i++)
{
- if (dpo_id_is_valid (&dpo_ctx->next_hops[i]))
- {
- if (hicn_strategy_mw_ctx->weight[next_hop_index] <
- hicn_strategy_mw_ctx->weight[i])
- {
- next_hop_index = i;
- }
- }
+ if (hicn_strategy_mw_ctx->weight[next_hop_index] <
+ hicn_strategy_mw_ctx->weight[i])
+ {
+ next_hop_index = i;
+ }
}
- if (!dpo_id_is_valid (&dpo_ctx->next_hops[next_hop_index]))
- return HICN_ERROR_STRATEGY_NH_NOT_FOUND;
-
- *outface = (dpo_id_t *) & dpo_ctx->next_hops[next_hop_index];
+ *outface = dpo_ctx->next_hops[next_hop_index];
return HICN_ERROR_NONE;
}
diff --git a/hicn-plugin/src/strategies/strategy_mw.h b/hicn-plugin/src/strategies/strategy_mw.h
index f64f1fdc7..9e0078b23 100644
--- a/hicn-plugin/src/strategies/strategy_mw.h
+++ b/hicn-plugin/src/strategies/strategy_mw.h
@@ -19,6 +19,13 @@
#include "../strategy.h"
/**
+ * @file strategy_mw.h
+ *
+ * This file implements the maximum weight strategy. In this
+ * strategy the choosen next hop is one with the maximum weight.
+ */
+
+/**
* @brief Return the vft for the Maximum Weight strategy
*/
hicn_strategy_vft_t *hicn_mw_strategy_get_vft (void);
diff --git a/hicn-plugin/src/strategies/strategy_mw_cli.c b/hicn-plugin/src/strategies/strategy_mw_cli.c
index 701f96fa7..636d7effa 100644
--- a/hicn-plugin/src/strategies/strategy_mw_cli.c
+++ b/hicn-plugin/src/strategies/strategy_mw_cli.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -97,7 +97,7 @@ hicn_mw_strategy_cli_set_weight_command_fn (vlib_main_t * vm,
(hicn_strategy_mw_ctx_t *) hicn_dpo_ctx;
int idx = ~0;
for (int i = 0; i < hicn_dpo_ctx->entry_count; i++)
- if (hicn_dpo_ctx->next_hops[i].dpoi_index == (index_t) faceid)
+ if (hicn_dpo_ctx->next_hops[i] == faceid)
idx = i;
if (idx == ~0)
diff --git a/hicn-plugin/src/strategies/strategy_rr.c b/hicn-plugin/src/strategies/strategy_rr.c
index cdcca7f2a..4c65ce52a 100644
--- a/hicn-plugin/src/strategies/strategy_rr.c
+++ b/hicn-plugin/src/strategies/strategy_rr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -26,7 +26,7 @@ void hicn_receive_data_rr (index_t dpo_idx, int nh_idx);
void hicn_add_interest_rr (index_t dpo_idx, hicn_hash_entry_t * pit_entry);
void hicn_on_interest_timeout_rr (index_t dpo_idx);
u32 hicn_select_next_hop_rr (index_t dpo_idx, int *nh_idx,
- dpo_id_t ** outface);
+ hicn_face_id_t* outface);
u8 *hicn_strategy_format_trace_rr (u8 * s, hicn_strategy_trace_t * t);
u8 *hicn_strategy_format_rr (u8 * s, va_list * ap);
@@ -51,7 +51,7 @@ hicn_rr_strategy_get_vft (void)
/* DPO should be give in input as it containes all the information to calculate the next hops*/
u32
-hicn_select_next_hop_rr (index_t dpo_idx, int *nh_idx, dpo_id_t ** outface)
+hicn_select_next_hop_rr (index_t dpo_idx, int *nh_idx, hicn_face_id_t* outface)
{
hicn_dpo_ctx_t *dpo_ctx = hicn_strategy_dpo_ctx_get (dpo_idx);
@@ -61,15 +61,8 @@ hicn_select_next_hop_rr (index_t dpo_idx, int *nh_idx, dpo_id_t ** outface)
hicn_strategy_rr_ctx_t *hicn_strategy_rr_ctx =
(hicn_strategy_rr_ctx_t *) dpo_ctx->data;
- if (dpo_id_is_valid
- (&dpo_ctx->next_hops[hicn_strategy_rr_ctx->current_nhop]))
- {
- *outface =
- (dpo_id_t *) & dpo_ctx->next_hops[hicn_strategy_rr_ctx->current_nhop];
-
- }
- else
- return HICN_ERROR_STRATEGY_NH_NOT_FOUND;
+ *outface =
+ dpo_ctx->next_hops[hicn_strategy_rr_ctx->current_nhop];
hicn_strategy_rr_ctx->current_nhop =
(hicn_strategy_rr_ctx->current_nhop + 1) % dpo_ctx->entry_count;
diff --git a/hicn-plugin/src/strategies/strategy_rr.h b/hicn-plugin/src/strategies/strategy_rr.h
index 3936845fe..4dfe76b43 100644
--- a/hicn-plugin/src/strategies/strategy_rr.h
+++ b/hicn-plugin/src/strategies/strategy_rr.h
@@ -19,6 +19,13 @@
#include "../strategy.h"
/**
+ * @file strategy_rr.h
+ *
+ * This file implements the round robin strategy. In this
+ * strategy the next hop is choosen in a round robin way.
+ */
+
+/**
* @brief Return the vft for the Round Robin strategy
*/
hicn_strategy_vft_t *hicn_rr_strategy_get_vft (void);
diff --git a/hicn-plugin/src/strategy.h b/hicn-plugin/src/strategy.h
index c18ae4eea..d949f38a4 100644
--- a/hicn-plugin/src/strategy.h
+++ b/hicn-plugin/src/strategy.h
@@ -22,21 +22,20 @@
#include "faces/face.h"
/**
- * @File
+ * @file strategy.h
*
* A strategy is defined as a dpo and a set of function (vft) that will be called
* during the packet processing. A strategy is associated to an entry in the fib by
* assigning the corresponding dpo to the fib entry. The dpo points to a hICN dpo
* context (ctx) which contains the information needed by the strategy to compute
* the next hop. Each strategy hash its own dpo type, which means that the dpo_type
- * uniquely identify a strategy and its vft. The strategy node will use the dpo_type
+ * uniquely identifies a strategy and its vft. The strategy node will use the dpo_type
* to retrieve the corresponding vft.
* Here we provide:
* - a template for the callbacks to implement in order to create a new strategy
* (hicn_fwd_strategy_t)
- * - the base structure for a strategy node
- * (list of next vpp nodes, errors, tracing and the main function processing an
- * interest and calling hicn_select_next_hop)
+ * - a default implementation for the strategy node which will call the strategy
+ * functions while processing the interest packets
*/
/* Trace context struct */
@@ -54,7 +53,7 @@ typedef struct hicn_strategy_vft_s
void (*hicn_on_interest_timeout) (index_t dpo_idx);
void (*hicn_add_interest) (index_t dpo_idx, hicn_hash_entry_t * pit_entry);
u32 (*hicn_select_next_hop) (index_t dpo_idx, int *nh_idx,
- dpo_id_t ** outface);
+ hicn_face_id_t* outface);
u8 *(*hicn_format_strategy_trace) (u8 *, hicn_strategy_trace_t *);
u8 *(*hicn_format_strategy) (u8 * s, va_list * ap);
/**< Format an hICN dpo*/
@@ -64,10 +63,31 @@ typedef enum
{
HICN_STRATEGY_NEXT_INTEREST_HITPIT,
HICN_STRATEGY_NEXT_INTEREST_HITCS,
+ HICN_STRATEGY_NEXT_INTEREST_FACE4,
+ HICN_STRATEGY_NEXT_INTEREST_FACE6,
HICN_STRATEGY_NEXT_ERROR_DROP,
HICN_STRATEGY_N_NEXT,
} hicn_strategy_next_t;
+const static char *const hicn_ip6_nodes[] =
+{
+ "hicn6-iface-input", // this is the name you give your node in VLIB_REGISTER_NODE
+ NULL,
+};
+
+const static char *const hicn_ip4_nodes[] =
+{
+ "hicn4-iface-input", // this is the name you give your node in VLIB_REGISTER_NODE
+ NULL,
+};
+
+const static char *const *const hicn_nodes_strategy[DPO_PROTO_NUM] =
+{
+ [DPO_PROTO_IP6] = hicn_ip6_nodes,
+ [DPO_PROTO_IP4] = hicn_ip4_nodes,
+};
+
+
extern vlib_node_registration_t hicn_strategy_node;
#endif /* //__HICN_STRATEGY__ */
diff --git a/hicn-plugin/src/strategy_dpo_ctx.c b/hicn-plugin/src/strategy_dpo_ctx.c
index 6ec1407fb..342c78bb5 100644
--- a/hicn-plugin/src/strategy_dpo_ctx.c
+++ b/hicn-plugin/src/strategy_dpo_ctx.c
@@ -97,7 +97,7 @@ hicn_strategy_dpo_ctx_alloc ()
}
int
-hicn_strategy_dpo_ctx_add_nh (const dpo_id_t * nh, hicn_dpo_ctx_t * dpo_ctx,
+hicn_strategy_dpo_ctx_add_nh (hicn_face_id_t nh, hicn_dpo_ctx_t * dpo_ctx,
u8 * pos)
{
@@ -106,12 +106,12 @@ hicn_strategy_dpo_ctx_add_nh (const dpo_id_t * nh, hicn_dpo_ctx_t * dpo_ctx,
/* Iterate through the list of faces to find if the face is already a next hop */
for (int i = 0; i < dpo_ctx->entry_count; i++)
{
- if (!memcmp (nh, &dpo_ctx->next_hops[i], sizeof (dpo_id_t)))
+ if (nh == dpo_ctx->next_hops[i])
{
/* If face is marked as deleted, ignore it */
hicn_face_t *face =
- hicn_dpoi_get_from_idx (dpo_ctx->next_hops[i].dpoi_index);
- if (face->shared.flags & HICN_FACE_FLAGS_DELETED)
+ hicn_dpoi_get_from_idx (dpo_ctx->next_hops[i]);
+ if (face->flags & HICN_FACE_FLAGS_DELETED)
{
continue;
}
@@ -125,7 +125,8 @@ hicn_strategy_dpo_ctx_add_nh (const dpo_id_t * nh, hicn_dpo_ctx_t * dpo_ctx,
return HICN_ERROR_DPO_CTX_NHOPS_NS;
}
- clib_memcpy (&dpo_ctx->next_hops[empty], nh, sizeof (dpo_id_t));
+ dpo_ctx->next_hops[empty] = nh;
+ hicn_face_lock_with_id (nh);
dpo_ctx->entry_count++;
*pos = empty;
@@ -137,13 +138,13 @@ hicn_strategy_dpo_ctx_del_nh (hicn_face_id_t face_id,
hicn_dpo_ctx_t * dpo_ctx)
{
int ret = HICN_ERROR_DPO_CTX_NOT_FOUND;
- dpo_id_t invalid = NEXT_HOP_INVALID;
+ hicn_face_id_t invalid = NEXT_HOP_INVALID;
for (int i = 0; i < dpo_ctx->entry_count; i++)
{
- if (dpo_ctx->next_hops[i].dpoi_index == face_id)
+ if (dpo_ctx->next_hops[i] == face_id)
{
- hicn_face_unlock (&dpo_ctx->next_hops[i]);
+ hicn_face_unlock_with_id (dpo_ctx->next_hops[i]);
dpo_ctx->entry_count--;
dpo_ctx->next_hops[i] = dpo_ctx->next_hops[dpo_ctx->entry_count];
dpo_ctx->next_hops[dpo_ctx->entry_count] = invalid;
diff --git a/hicn-plugin/src/strategy_dpo_ctx.h b/hicn-plugin/src/strategy_dpo_ctx.h
index 737071766..214ed88ad 100644
--- a/hicn-plugin/src/strategy_dpo_ctx.h
+++ b/hicn-plugin/src/strategy_dpo_ctx.h
@@ -22,27 +22,30 @@
#include "params.h"
#include "faces/face.h"
-//FIB table for hicn. 0 is the default one used by ip
-#define HICN_FIB_TABLE 0
-
-#define NEXT_HOP_INVALID DPO_INVALID
-
-#define INIT_SEQ 0
-
/**
- * @brief Definition of the general hICN DPO ctx (shared among all the strategies).
+ * @file strategy_dpo_ctx.h
+ *
+ * This file implements the general hICN DPO ctx (shared among all the strategies).
*
* An hICN DPO ctx contains the list of next hops, auxiliaries fields to maintain the dpo, map-me
* specifics (tfib_entry_count and seq), the dpo_type and 64B to let each strategy to store additional
- * information. Each next hop is a dpo_id_t that refers to an hICN face. The dpo_type is used to
- * identify the strategy and to retrieve the vft corresponding to the strategy (see strategy.h)
- * and to the dpo ctx (see strategy_dpo_manager.h)
+ * information. Each next hop is an hicn_face_id_t that refers to an index for an hICN face. The
+ * dpo_type is used to identify the strategy and to retrieve the vft corresponding to the strategy
+ * (see strategy.h) and to the dpo ctx (see strategy_dpo_manager.h)
*/
+
+//FIB table for hicn. 0 is the default one used by ip
+#define HICN_FIB_TABLE 10
+
+#define NEXT_HOP_INVALID ~0
+
+#define INIT_SEQ 0
+
typedef struct __attribute__ ((packed)) hicn_dpo_ctx_s
{
CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
- /* 8B*5 = 40B */
- dpo_id_t next_hops[HICN_PARAM_FIB_ENTRY_NHOPS_MAX];
+ /* 4B*10 = 40B */
+ hicn_face_id_t next_hops[HICN_PARAM_FIB_ENTRY_NHOPS_MAX];
/* 40B + 4B = 44B */
u32 locks;
/* 44B + 1B = 45B */
@@ -51,17 +54,30 @@ typedef struct __attribute__ ((packed)) hicn_dpo_ctx_s
/* Number of TFIB entries (stored at the end of the next_hops array */
u8 tfib_entry_count;
+ dpo_type_t dpo_type;
+
/* 46B + 2B = 48B */
- u16 padding; /* To align to 8B */
+ u8 padding; /* To align to 8B */
/* 48 + 4B = 52; last sequence number */
- seq_t seq;
+ u32 seq;
- /* 48 + 1B = 53; last sequence number */
- dpo_type_t dpo_type;
+ /* 52 + 12 = 64 */
+ fib_node_t fib_node;
CLIB_CACHE_LINE_ALIGN_MARK (cacheline1);
- u8 data[CLIB_CACHE_LINE_BYTES];
+
+ fib_node_index_t fib_entry_index;
+
+ u32 fib_sibling;
+
+ union
+ {
+ u32 padding_proto;
+ fib_protocol_t proto;
+ };
+
+ u8 data[CLIB_CACHE_LINE_BYTES - 12];
} hicn_dpo_ctx_t;
@@ -76,10 +92,10 @@ extern hicn_dpo_ctx_t *hicn_strategy_dpo_ctx_pool;
* @param dpo_type Type of dpo. It identifies the strategy.
*/
always_inline void
-init_dpo_ctx (hicn_dpo_ctx_t * dpo_ctx, const dpo_id_t * next_hop,
- int nh_len, dpo_type_t dpo_type)
+init_dpo_ctx (hicn_dpo_ctx_t * dpo_ctx, const hicn_face_id_t * next_hop,
+ int nh_len, dpo_type_t dpo_type, dpo_proto_t proto)
{
- dpo_id_t invalid = NEXT_HOP_INVALID;
+ hicn_face_id_t invalid = NEXT_HOP_INVALID;
dpo_ctx->entry_count = 0;
dpo_ctx->locks = 0;
@@ -89,9 +105,11 @@ init_dpo_ctx (hicn_dpo_ctx_t * dpo_ctx, const dpo_id_t * next_hop,
dpo_ctx->seq = INIT_SEQ;
dpo_ctx->dpo_type = dpo_type;
+ dpo_ctx->proto = proto;
+
for (int i = 0; i < HICN_PARAM_FIB_ENTRY_NHOPS_MAX && i < nh_len; i++)
{
- clib_memcpy (&dpo_ctx->next_hops[i], &next_hop[i], sizeof (dpo_id_t));
+ dpo_ctx->next_hops[i] = next_hop[i];
dpo_ctx->entry_count++;
}
@@ -151,7 +169,7 @@ void hicn_strategy_dpo_ctx_unlock (dpo_id_t * dpo);
* otherwise HICN_ERROR_DPO_CTX_NOT_FOUND
*/
int
-hicn_strategy_dpo_ctx_add_nh (const dpo_id_t * nh, hicn_dpo_ctx_t * dpo_ctx,
+hicn_strategy_dpo_ctx_add_nh (hicn_face_id_t nh, hicn_dpo_ctx_t * dpo_ctx,
u8 * pos);
/**
diff --git a/hicn-plugin/src/strategy_dpo_manager.h b/hicn-plugin/src/strategy_dpo_manager.h
index 63fcb930b..e96e050d9 100644
--- a/hicn-plugin/src/strategy_dpo_manager.h
+++ b/hicn-plugin/src/strategy_dpo_manager.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -20,10 +20,26 @@
#include "strategy.h"
/**
+ * @file strategy_dpo_manager.h
+ *
+ * This file implements structs and helper functions to manipulate hICN dpo.
+ * An hICN DPO is a combination of:
+ * - a hICN DPO ctx (context) that holds the structure containing the
+ * information to choose the next hop,
+ * - a dpo vft that specify how to update the hICN DPO ctx when a next hop is
+ * added, deleted or updated,
+ * - a strategy containing (see strategy.h): (i) the vpp node that processes Interest packets
+ * subjected to such strategy, (ii) the definition of the vft that defines
+ * the hICN strategy functions
+ * An hICN DPO is places as the sole next hop in the vpp loadbalancer, and it containes
+ * a list of next hops that will be used by the associated strategy when forwarding
+ * interest packets.
+ */
+
+/**
* @brief Definition of the virtual function table for a hICN DPO.
*
- * An hICN dpo is a combination of a dpo context (hicn_dpo_ctx or struct that
- * extends a hicn_dpo_ctx) and a strategy node. The following virtual function table
+ * The following virtual function table
* template that glues together the fuction to interact with the context and the
* creating the dpo
*/
@@ -35,8 +51,8 @@ typedef struct hicn_dpo_vft_s
dpo_type_t (*hicn_dpo_get_type) (void);
/**< Return the type of the hICN dpo */
void (*hicn_dpo_module_init) (void); /**< Initialize the hICN dpo */
- void (*hicn_dpo_create) (dpo_proto_t proto, const dpo_id_t * nh, int nh_len, index_t * dpo_idx); /**< Create the context of the hICN dpo */
- int (*hicn_dpo_add_update_nh) (const dpo_id_t * nh, index_t dpo_idx); /**< Add a next hop to the hICN dpo context */
+ void (*hicn_dpo_create) (fib_protocol_t proto, const hicn_face_id_t * nh, int nh_len, index_t * dpo_idx); /**< Create the context of the hICN dpo */
+ int (*hicn_dpo_add_update_nh) (hicn_face_id_t nh, index_t dpo_idx); /**< Add a next hop to the hICN dpo context */
int (*hicn_dpo_del_nh) (hicn_face_id_t face_id, index_t dpo_idx);
u8 *(*hicn_dpo_format) (u8 * s, int, ...);
/**< Format an hICN dpo*/
@@ -48,37 +64,18 @@ typedef struct hicn_dpo_vft_s
*/
extern hicn_dpo_vft_t default_dpo;
-const static char *const hicn_ip6_nodes[] = {
- "hicn-iface-ip6-input", // this is the name you give your node in VLIB_REGISTER_NODE
- NULL,
-};
-
-const static char *const hicn_ip4_nodes[] = {
- "hicn-iface-ip4-input", // this is the name you give your node in VLIB_REGISTER_NODE
- NULL,
-};
-
-const static char *const *const hicn_nodes_strategy[DPO_PROTO_NUM] = {
- [DPO_PROTO_IP6] = hicn_ip6_nodes,
- [DPO_PROTO_IP4] = hicn_ip4_nodes,
-};
-
/**
* @brief Register a new hICN dpo to the manager.
*
- * An hICN DPO is a combination of:
- * - a hICN DPO ctx (context) that holds the structure containing the
- * information to choose the next hop,
- * - a strategy containing: (i) the vpp node that processes Interest packets
- * subjected to such strategy, (ii) the definition of the vft that defines
- * the hICN strategy functions
- * Registering a hICN DPO allows the plugin to be aware of the new dpo an be
- * able to apply it to the FIB entries.
+ * Registering a hICN DPO allows the plugin to be aware of the new dpo an be
+ * able to apply it to the FIB entries.
*
* @param hicn_nodes A list of vpp to which pass an interest that matches with
* the FIB entry to which the hICN DPO is applied. This list must contain the
* name of the strategy node (or nodes in case of differentiation between IPv4
- * and IPv6).
+ * and IPv6). Unless really needed otherwise (i.e., different implementation of
+ * iface input), the list of node to use should be one provided in the strategy.h
+ * (hicn_nodes_strategy)
* @param hicn_dpo_vft The structure holding the virtual function table to
* interact with the hICN dpo and its context.
* @param hicn_strategy_vft The structure holding the virtual function table
diff --git a/hicn-plugin/src/strategy_node.c b/hicn-plugin/src/strategy_node.c
index 27d1e2a03..0659a871a 100644
--- a/hicn-plugin/src/strategy_node.c
+++ b/hicn-plugin/src/strategy_node.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -64,7 +64,7 @@ hicn_strategy_format_trace (u8 * s, va_list * args)
always_inline int
hicn_new_interest (hicn_strategy_runtime_t * rt, vlib_buffer_t * b0,
u32 * next, f64 tnow, u8 * nameptr,
- u16 namelen, dpo_id_t * outface, int nh_idx,
+ 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)
@@ -123,15 +123,14 @@ hicn_new_interest (hicn_strategy_runtime_t * rt, vlib_buffer_t * b0,
hash_entry);
/* Add face */
- hicn_face_db_add_face_dpo (&hicnb0->face_dpo_id, &(pitp->u.pit.faces));
+ hicn_face_db_add_face (hicnb0->face_id, &(pitp->u.pit.faces));
- /* Remove lock on the dpo stored in the vlib_buffer */
- //dpo_unlock (&hicnb0->face_dpo_id);
+ *next = isv6 ? HICN_STRATEGY_NEXT_INTEREST_FACE6 :
+ HICN_STRATEGY_NEXT_INTEREST_FACE4;
- *next = outface->dpoi_next_node;
-
- vnet_buffer (b0)->ip.adj_index[VLIB_TX] = outface->dpoi_index;
+ vnet_buffer (b0)->ip.adj_index[VLIB_TX] = outface;
stats->pkts_interest_count++;
+ pitp->u.pit.pe_txnh = nh_idx;
}
else
{
@@ -197,7 +196,7 @@ hicn_strategy_fn (vlib_main_t * vm,
hicn_header_t *hicn0;
vlib_buffer_t *b0;
u32 bi0;
- dpo_id_t *outface = NULL;
+ hicn_face_id_t outface;
int nh_idx;
u32 next0 = next_index;
int ret;
@@ -310,6 +309,8 @@ VLIB_REGISTER_NODE (hicn_strategy_node) =
{
[HICN_STRATEGY_NEXT_INTEREST_HITPIT] = "hicn-interest-hitpit",
[HICN_STRATEGY_NEXT_INTEREST_HITCS] = "hicn-interest-hitcs",
+ [HICN_STRATEGY_NEXT_INTEREST_FACE4] = "hicn4-face-output",
+ [HICN_STRATEGY_NEXT_INTEREST_FACE6] = "hicn6-face-output",
[HICN_STRATEGY_NEXT_ERROR_DROP] = "error-drop",
},
};
diff --git a/hicn-plugin/src/faces/ip/iface_ip_node.h b/hicn-plugin/src/udp_tunnels/udp_decap.h
index 36923f069..9ddb8a73b 100644
--- a/hicn-plugin/src/faces/ip/iface_ip_node.h
+++ b/hicn-plugin/src/udp_tunnels/udp_decap.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2020 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:
@@ -13,23 +13,20 @@
* limitations under the License.
*/
-#ifndef __HICN_IFACE_IP_NODE_H__
-#define __HICN_IFACE_IP_NODE_H__
-
-#include <vlib/vlib.h>
-#include <vnet/vnet.h>
+#ifndef __UDP_DECAP_H__
+#define __UDP_DECAP_H__
/**
- * @brief Initialize the ip iface module
+ * @file udp_decap.h
+ *
+ * Implements the udp decapsulation for udp tunnels
+ *
+ * Udp decap nodes follow the ip4/6-local nodes and their purpose
+ * is to retrieve the udp tunnel for the incoming packet. If a tunnel does
+ * not exist the packet is dropped.
+ * The following node to the udp decap nodes are the ip4/6-lookup nodes.
*/
-void hicn_iface_ip_init (vlib_main_t * vm);
-#endif // __HICN_IFACE_IP_NODE_H__
+extern vlib_node_registration_t udp_decap_node;
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
+#endif // __UDP_DECAP_H__
diff --git a/hicn-plugin/src/udp_tunnels/udp_decap_node.c b/hicn-plugin/src/udp_tunnels/udp_decap_node.c
new file mode 100644
index 000000000..5603f20f9
--- /dev/null
+++ b/hicn-plugin/src/udp_tunnels/udp_decap_node.c
@@ -0,0 +1,623 @@
+/*
+ * Copyright (c) 2020 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 <vnet/fib/fib_table.h>
+
+#include "udp_tunnel.h"
+#include "../mgmt.h"
+#include "../hicn.h"
+#include "../strategy_dpo_ctx.h"
+
+vlib_node_registration_t udp_decap_node;
+
+static char *udp_decap_error_strings[] = {
+#define _(sym, string) string,
+ foreach_hicnfwd_error
+#undef _
+};
+
+/* Trace context struct */
+typedef enum
+{
+ UDP4_DECAP_NEXT_LOOKUP_IP4,
+ UDP4_DECAP_NEXT_LOOKUP_IP6,
+ UDP4_DECAP_N_NEXT,
+} udp4_decap_next_t;
+
+typedef enum
+{
+ UDP6_DECAP_NEXT_LOOKUP_IP4,
+ UDP6_DECAP_NEXT_LOOKUP_IP6,
+ UDP6_DECAP_N_NEXT,
+} udp6_decap_next_t;
+
+typedef struct udp4_decap_trace_t_
+{
+ ip4_header_t ip;
+ udp_header_t udp;
+} udp4_decap_trace_t;
+
+typedef struct udp6_decap_trace_t_
+{
+ ip6_header_t ip;
+ udp_header_t udp;
+} udp6_decap_trace_t;
+
+typedef struct udp_decap_trace_t_
+{
+ union
+ {
+ udp4_decap_trace_t udp4;
+ udp6_decap_trace_t udp6;
+ };
+
+ u8 isv6;
+ u8 ishicn;
+} udp_decap_trace_t;
+
+
+static u8 *
+format_udp_decap_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 *);
+ udp_decap_trace_t *t;
+
+ t = va_arg (*args, udp_decap_trace_t *);
+
+ if (t->isv6)
+ {
+ s = format (s, "%U\n %U \n %s",
+ format_ip4_header, &t->udp6.ip, sizeof (t->udp6.ip),
+ format_udp_header, &t->udp6.udp, sizeof (t->udp6.udp),
+ t->ishicn ? "hICN udp tunnel" : "");
+ }
+ else
+ {
+ s = format (s, "%U\n %U \n %s",
+ format_ip4_header, &t->udp4.ip, sizeof (t->udp4.ip),
+ format_udp_header, &t->udp4.udp, sizeof (t->udp4.udp),
+ t->ishicn ? "hICN udp tunnel" : "");
+ }
+ return (s);
+}
+
+static_always_inline void
+udp_decap_trace_buffer (vlib_main_t * vm, vlib_node_runtime_t * node,
+ u8 isv6, vlib_buffer_t * b)
+{
+ if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
+ (b->flags & VLIB_BUFFER_IS_TRACED)))
+ {
+ udp_decap_trace_t *t =
+ vlib_add_trace (vm, node, b, sizeof (*t));
+ t->isv6 = isv6;
+ hicn_buffer_t *hb = hicn_get_buffer(b);
+
+ if (isv6)
+ {
+ clib_memcpy(&(t->udp6.udp), vlib_buffer_get_current(b) + sizeof(ip6_header_t), sizeof(udp_header_t));
+ clib_memcpy(&(t->udp6.ip), vlib_buffer_get_current(b), sizeof(ip6_header_t));
+ t->ishicn = hb->flags & hb->flags & HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL;
+ }
+ else
+ {
+ clib_memcpy(&(t->udp4.udp), vlib_buffer_get_current(b) + sizeof(ip4_header_t), sizeof(udp_header_t));
+ clib_memcpy(&(t->udp4.ip), vlib_buffer_get_current(b), sizeof(ip4_header_t));
+ t->ishicn = hb->flags & HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL;
+ }
+ }
+}
+
+static uword
+udp4_decap_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
+ vlib_frame_t * frame)
+{
+ u32 n_left_from, *from, *to_next, next_index;
+
+ 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);
+
+ /* Dual loop, X2 */
+ while (n_left_from >= 8 && n_left_to_next >= 4)
+ {
+ vlib_buffer_t *b0, *b1, *b2, *b3;
+ u32 bi0, bi1, bi2, bi3;
+ u32 next0, next1, next2, next3;
+
+ {
+ 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);
+ }
+
+ bi0 = from[0];
+ bi1 = from[1];
+ bi2 = from[2];
+ bi3 = from[3];
+
+ from += 4;
+ n_left_from -= 4;
+ to_next[0] = bi0;
+ to_next[1] = bi1;
+ to_next[2] = bi2;
+ to_next[3] = bi3;
+
+ to_next += 4;
+ n_left_to_next -= 4;
+
+ b0 = vlib_get_buffer (vm, bi0);
+ b1 = vlib_get_buffer (vm, bi1);
+ b2 = vlib_get_buffer (vm, bi2);
+ b3 = vlib_get_buffer (vm, bi3);
+
+ u8 *ptr0 = vlib_buffer_get_current (b0);
+ u8 *ptr1 = vlib_buffer_get_current (b1);
+ u8 *ptr2 = vlib_buffer_get_current (b2);
+ u8 *ptr3 = vlib_buffer_get_current (b3);
+ u8 v0 = *ptr0 & 0xf0;
+ u8 v1 = *ptr1 & 0xf0;
+ u8 v2 = *ptr2 & 0xf0;
+ u8 v3 = *ptr3 & 0xf0;
+
+ u8 advance = sizeof(ip4_header_t) + sizeof(udp_header_t);
+
+ vlib_buffer_advance(b0, -advance);
+ vlib_buffer_advance(b1, -advance);
+ vlib_buffer_advance(b2, -advance);
+ vlib_buffer_advance(b3, -advance);
+
+ u8 *outer_ptr0 = vlib_buffer_get_current (b0);
+ u8 *outer_ptr1 = vlib_buffer_get_current (b1);
+ u8 *outer_ptr2 = vlib_buffer_get_current (b2);
+ u8 *outer_ptr3 = vlib_buffer_get_current (b3);
+ u8 outer_v0 = *outer_ptr0 & 0xf0;
+ u8 outer_v1 = *outer_ptr1 & 0xf0;
+ u8 outer_v2 = *outer_ptr2 & 0xf0;
+ u8 outer_v3 = *outer_ptr3 & 0xf0;
+
+ ip46_address_t src0 = {0};
+ ip46_address_t src1 = {0};
+ ip46_address_t src2 = {0};
+ ip46_address_t src3 = {0};
+
+ ip46_address_t dst0 = {0};
+ ip46_address_t dst1 = {0};
+ ip46_address_t dst2 = {0};
+ ip46_address_t dst3 = {0};
+
+ udp_header_t * udp0 = NULL;
+ udp_header_t * udp1 = NULL;
+ udp_header_t * udp2 = NULL;
+ udp_header_t * udp3 = NULL;
+
+ ip46_address_set_ip4(&src0, &((ip4_header_t *)outer_ptr0)->src_address);
+ ip46_address_set_ip4(&dst0, &((ip4_header_t *)outer_ptr0)->dst_address);
+ udp0 = (udp_header_t *)(outer_ptr0 + sizeof(ip4_header_t));
+ next0 = v0 == 0x40? UDP4_DECAP_NEXT_LOOKUP_IP4 : UDP4_DECAP_NEXT_LOOKUP_IP6;
+
+ ip46_address_set_ip4(&src1, &((ip4_header_t *)outer_ptr1)->src_address);
+ ip46_address_set_ip4(&dst1, &((ip4_header_t *)outer_ptr1)->dst_address);
+ udp1 = (udp_header_t *)(outer_ptr1 + sizeof(ip4_header_t));
+ next1 = v1 == 0x40? UDP4_DECAP_NEXT_LOOKUP_IP4 : UDP4_DECAP_NEXT_LOOKUP_IP6;
+
+ ip46_address_set_ip4(&src2, &((ip4_header_t *)outer_ptr2)->src_address);
+ ip46_address_set_ip4(&dst2, &((ip4_header_t *)outer_ptr2)->dst_address);
+ udp2 = (udp_header_t *)(outer_ptr2 + sizeof(ip4_header_t));
+ next2 = v2 == 0x40? UDP4_DECAP_NEXT_LOOKUP_IP4 : UDP4_DECAP_NEXT_LOOKUP_IP6;
+
+ ip46_address_set_ip4(&src3, &((ip4_header_t *)outer_ptr3)->src_address);
+ ip46_address_set_ip4(&dst3, &((ip4_header_t *)outer_ptr3)->dst_address);
+ udp3 = (udp_header_t *)(outer_ptr3 + sizeof(ip4_header_t));
+ next3 = v3 == 0x40? UDP4_DECAP_NEXT_LOOKUP_IP4 : UDP4_DECAP_NEXT_LOOKUP_IP6;
+
+ hicn_buffer_t *hicnb0, *hicnb1, *hicnb2, *hicnb3;
+ hicnb0 = hicn_get_buffer(b0);
+ hicnb1 = hicn_get_buffer(b1);
+ hicnb2 = hicn_get_buffer(b2);
+ hicnb3 = hicn_get_buffer(b3);
+
+
+ /* Udp encap-decap tunnels have dst and src addresses and port swapped */
+ vnet_buffer (b0)->ip.adj_index[VLIB_RX] = udp_tunnel_get(&dst0, &src0, udp0->dst_port, udp0->src_port);
+ vnet_buffer (b1)->ip.adj_index[VLIB_RX] = udp_tunnel_get(&dst1, &src1, udp1->dst_port, udp1->src_port);
+ vnet_buffer (b2)->ip.adj_index[VLIB_RX] = udp_tunnel_get(&dst2, &src2, udp2->dst_port, udp2->src_port);
+ vnet_buffer (b3)->ip.adj_index[VLIB_RX] = udp_tunnel_get(&dst3, &src3, udp3->dst_port, udp3->src_port);
+
+ if (vnet_buffer (b0)->ip.adj_index[VLIB_RX] !=
+ UDP_TUNNEL_INVALID)
+ hicnb0->flags |= (outer_v0 == 0x40? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL);
+
+ if (vnet_buffer (b1)->ip.adj_index[VLIB_RX] !=
+ UDP_TUNNEL_INVALID)
+ hicnb1->flags |= (outer_v1 == 0x40? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL);
+
+ if (vnet_buffer (b2)->ip.adj_index[VLIB_RX] !=
+ UDP_TUNNEL_INVALID)
+ hicnb2->flags |= (outer_v2 == 0x40? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL);
+
+ if (vnet_buffer (b3)->ip.adj_index[VLIB_RX] !=
+ UDP_TUNNEL_INVALID)
+ hicnb3->flags |= (outer_v3 == 0x40? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL);
+
+ udp_decap_trace_buffer (vm, node, 1, b0);
+ udp_decap_trace_buffer (vm, node, 1, b1);
+ udp_decap_trace_buffer (vm, node, 1, b2);
+ udp_decap_trace_buffer (vm, node, 1, b3);
+
+ vlib_buffer_advance(b0, advance);
+ vlib_buffer_advance(b1, advance);
+ vlib_buffer_advance(b2, advance);
+ vlib_buffer_advance(b3, advance);
+
+ vlib_validate_buffer_enqueue_x4 (vm, node, next_index, to_next,
+ n_left_to_next, bi0, bi1, bi2, bi3,
+ next0, next1, next2, next3);
+ }
+
+ /* Dual loop, X1 */
+ while (n_left_from > 0 && n_left_to_next > 0)
+ {
+ vlib_buffer_t *b0;
+ u32 bi0;
+ /* udp_encap_t *udp_tunnel0 = NULL; */
+ u32 next0;
+
+ if (n_left_from > 1)
+ {
+ vlib_buffer_t *b1;
+ b1 = vlib_get_buffer (vm, from[1]);
+ CLIB_PREFETCH (b1, CLIB_CACHE_LINE_BYTES, STORE);
+ }
+
+ bi0 = from[0];
+ from += 1;
+ n_left_from -= 1;
+ to_next[0] = bi0;
+ to_next += 1;
+ n_left_to_next -= 1;
+
+ b0 = vlib_get_buffer (vm, bi0);
+
+ u8 *ptr0 = vlib_buffer_get_current (b0);
+ u8 v0 = *ptr0 & 0xf0;
+
+ u8 advance = sizeof(ip4_header_t) + sizeof(udp_header_t);;
+
+ vlib_buffer_advance(b0, -advance);
+
+ u8 *outer_ptr0 = vlib_buffer_get_current (b0);
+ u8 outer_v0 = *outer_ptr0 & 0xf0;
+
+ ip46_address_t src0 = {0};
+ ip46_address_t dst0 = {0};
+ udp_header_t * udp0 = NULL;
+
+ ip46_address_set_ip4(&src0, &((ip4_header_t *)outer_ptr0)->src_address);
+ ip46_address_set_ip4(&dst0, &((ip4_header_t *)outer_ptr0)->dst_address);
+ udp0 = (udp_header_t *)(outer_ptr0 + sizeof(ip4_header_t));
+ next0 = v0 == 0x40 ? UDP4_DECAP_NEXT_LOOKUP_IP4: UDP4_DECAP_NEXT_LOOKUP_IP6;
+
+ hicn_buffer_t *hicnb0 = hicn_get_buffer(b0);
+
+ vnet_buffer (b0)->ip.adj_index[VLIB_RX] = udp_tunnel_get(&dst0, &src0, udp0->dst_port, udp0->src_port);
+
+ if (vnet_buffer (b0)->ip.adj_index[VLIB_RX] !=
+ UDP_TUNNEL_INVALID)
+ hicnb0->flags |= (outer_v0 == 0x40 ? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL);
+
+ udp_decap_trace_buffer (vm, node, 1, b0);
+
+ vlib_buffer_advance(b0, advance);
+
+ 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);
+ }
+
+ return (frame->n_vectors);
+}
+
+
+/*
+ * Node registration for the interest forwarder node
+ */
+/* *INDENT-OFF* */
+VLIB_REGISTER_NODE(udp4_decap_node) =
+{
+ .function = udp4_decap_node_fn,
+ .name = "udp4-decap",
+ .vector_size = sizeof(u32),
+ .format_trace = format_udp_decap_trace,
+ .type = VLIB_NODE_TYPE_INTERNAL,
+ .n_errors = ARRAY_LEN(udp_decap_error_strings),
+ .error_strings = udp_decap_error_strings,
+ .n_next_nodes = UDP4_DECAP_N_NEXT,
+ /* edit / add dispositions here */
+ .next_nodes =
+ {
+ [UDP4_DECAP_NEXT_LOOKUP_IP4] = "ip4-lookup",
+ [UDP4_DECAP_NEXT_LOOKUP_IP6] = "ip6-lookup"
+ },
+};
+/* *INDENT-ON* */
+
+static uword
+udp6_decap_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
+ vlib_frame_t * frame)
+{
+ u32 n_left_from, *from, *to_next, next_index;
+
+ 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);
+
+ /* Dual loop, X2 */
+ while (n_left_from >= 8 && n_left_to_next >= 4)
+ {
+ vlib_buffer_t *b0, *b1, *b2, *b3;
+ u32 bi0, bi1, bi2, bi3;
+ u32 next0, next1, next2, next3;
+
+ {
+ 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);
+ }
+
+ bi0 = from[0];
+ bi1 = from[1];
+ bi2 = from[2];
+ bi3 = from[3];
+
+ from += 4;
+ n_left_from -= 4;
+ to_next[0] = bi0;
+ to_next[1] = bi1;
+ to_next[2] = bi2;
+ to_next[3] = bi3;
+
+ to_next += 4;
+ n_left_to_next -= 4;
+
+ b0 = vlib_get_buffer (vm, bi0);
+ b1 = vlib_get_buffer (vm, bi1);
+ b2 = vlib_get_buffer (vm, bi2);
+ b3 = vlib_get_buffer (vm, bi3);
+
+ u8 *ptr0 = vlib_buffer_get_current (b0);
+ u8 *ptr1 = vlib_buffer_get_current (b1);
+ u8 *ptr2 = vlib_buffer_get_current (b2);
+ u8 *ptr3 = vlib_buffer_get_current (b3);
+ u8 v0 = *ptr0 & 0xf0;
+ u8 v1 = *ptr1 & 0xf0;
+ u8 v2 = *ptr2 & 0xf0;
+ u8 v3 = *ptr3 & 0xf0;
+
+ u8 advance = sizeof(ip6_header_t) + sizeof(udp_header_t);
+
+ vlib_buffer_advance(b0, -advance);
+ vlib_buffer_advance(b1, -advance);
+ vlib_buffer_advance(b2, -advance);
+ vlib_buffer_advance(b3, -advance);
+
+ u8 *outer_ptr0 = vlib_buffer_get_current (b0);
+ u8 *outer_ptr1 = vlib_buffer_get_current (b1);
+ u8 *outer_ptr2 = vlib_buffer_get_current (b2);
+ u8 *outer_ptr3 = vlib_buffer_get_current (b3);
+ u8 outer_v0 = *outer_ptr0 & 0xf0;
+ u8 outer_v1 = *outer_ptr1 & 0xf0;
+ u8 outer_v2 = *outer_ptr2 & 0xf0;
+ u8 outer_v3 = *outer_ptr3 & 0xf0;
+
+ ip46_address_t src0 = {0};
+ ip46_address_t src1 = {0};
+ ip46_address_t src2 = {0};
+ ip46_address_t src3 = {0};
+
+ ip46_address_t dst0 = {0};
+ ip46_address_t dst1 = {0};
+ ip46_address_t dst2 = {0};
+ ip46_address_t dst3 = {0};
+
+ udp_header_t * udp0 = NULL;
+ udp_header_t * udp1 = NULL;
+ udp_header_t * udp2 = NULL;
+ udp_header_t * udp3 = NULL;
+
+ ip46_address_set_ip6(&src0, &((ip6_header_t *)outer_ptr0)->src_address);
+ ip46_address_set_ip6(&dst0, &((ip6_header_t *)outer_ptr0)->dst_address);
+ udp0 = (udp_header_t *)(outer_ptr0 + sizeof(ip6_header_t));
+ next0 = v0 == 0x40 ? UDP6_DECAP_NEXT_LOOKUP_IP4 : UDP6_DECAP_NEXT_LOOKUP_IP6;
+
+ ip46_address_set_ip6(&src1, &((ip6_header_t *)outer_ptr1)->src_address);
+ ip46_address_set_ip6(&dst1, &((ip6_header_t *)outer_ptr1)->dst_address);
+ udp1 = (udp_header_t *)(outer_ptr1 + sizeof(ip6_header_t));
+ next1 = v1 == 0x40 ? UDP6_DECAP_NEXT_LOOKUP_IP4 : UDP6_DECAP_NEXT_LOOKUP_IP6;
+
+ ip46_address_set_ip6(&src2, &((ip6_header_t *)outer_ptr2)->src_address);
+ ip46_address_set_ip6(&dst2, &((ip6_header_t *)outer_ptr2)->dst_address);
+ udp2 = (udp_header_t *)(outer_ptr2 + sizeof(ip6_header_t));
+ next2 = v2 == 0x40 ? UDP6_DECAP_NEXT_LOOKUP_IP4 : UDP6_DECAP_NEXT_LOOKUP_IP6;
+
+ ip46_address_set_ip6(&src3, &((ip6_header_t *)outer_ptr3)->src_address);
+ ip46_address_set_ip6(&dst3, &((ip6_header_t *)outer_ptr3)->dst_address);
+ udp3 = (udp_header_t *)(outer_ptr3 + sizeof(ip6_header_t));
+ next3 = v3 == 0x40 ? UDP6_DECAP_NEXT_LOOKUP_IP4 : UDP6_DECAP_NEXT_LOOKUP_IP6;
+
+ hicn_buffer_t *hicnb0, *hicnb1, *hicnb2, *hicnb3;
+ hicnb0 = hicn_get_buffer(b0);
+ hicnb1 = hicn_get_buffer(b1);
+ hicnb2 = hicn_get_buffer(b2);
+ hicnb3 = hicn_get_buffer(b3);
+
+
+ /* Udp encap-decap tunnels have dst and src addresses and port swapped */
+ vnet_buffer (b0)->ip.adj_index[VLIB_RX] = udp_tunnel_get(&dst0, &src0, udp0->dst_port, udp0->src_port);
+ vnet_buffer (b1)->ip.adj_index[VLIB_RX] = udp_tunnel_get(&dst1, &src1, udp1->dst_port, udp1->src_port);
+ vnet_buffer (b2)->ip.adj_index[VLIB_RX] = udp_tunnel_get(&dst2, &src2, udp2->dst_port, udp2->src_port);
+ vnet_buffer (b3)->ip.adj_index[VLIB_RX] = udp_tunnel_get(&dst3, &src3, udp3->dst_port, udp3->src_port);
+
+ if (vnet_buffer (b0)->ip.adj_index[VLIB_RX] !=
+ UDP_TUNNEL_INVALID)
+ hicnb0->flags |= (outer_v0 == 0x40? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL);
+
+ if (vnet_buffer (b1)->ip.adj_index[VLIB_RX] !=
+ UDP_TUNNEL_INVALID)
+ hicnb1->flags |= (outer_v1 == 0x40? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL);
+
+ if (vnet_buffer (b2)->ip.adj_index[VLIB_RX] !=
+ UDP_TUNNEL_INVALID)
+ hicnb2->flags |= (outer_v2 == 0x40? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL);
+
+ if (vnet_buffer (b3)->ip.adj_index[VLIB_RX] !=
+ UDP_TUNNEL_INVALID)
+ hicnb3->flags |= (outer_v3 == 0x40? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL);
+
+ udp_decap_trace_buffer (vm, node, 0, b0);
+ udp_decap_trace_buffer (vm, node, 0, b1);
+ udp_decap_trace_buffer (vm, node, 0, b2);
+ udp_decap_trace_buffer (vm, node, 0, b3);
+
+ vlib_buffer_advance(b0, advance);
+ vlib_buffer_advance(b1, advance);
+ vlib_buffer_advance(b2, advance);
+ vlib_buffer_advance(b3, advance);
+
+ vlib_validate_buffer_enqueue_x4 (vm, node, next_index, to_next,
+ n_left_to_next, bi0, bi1, bi2, bi3,
+ next0, next1, next2, next3);
+ }
+
+ /* Dual loop, X1 */
+ while (n_left_from > 0 && n_left_to_next > 0)
+ {
+ vlib_buffer_t *b0;
+ u32 bi0;
+ /* udp_encap_t *udp_tunnel0 = NULL; */
+ u32 next0;
+
+ if (n_left_from > 1)
+ {
+ vlib_buffer_t *b1;
+ b1 = vlib_get_buffer (vm, from[1]);
+ CLIB_PREFETCH (b1, CLIB_CACHE_LINE_BYTES, STORE);
+ }
+
+ bi0 = from[0];
+ from += 1;
+ n_left_from -= 1;
+ to_next[0] = bi0;
+ to_next += 1;
+ n_left_to_next -= 1;
+
+ b0 = vlib_get_buffer (vm, bi0);
+
+ u8 *ptr0 = vlib_buffer_get_current (b0);
+ u8 v0 = *ptr0 & 0xf0;
+
+ u8 advance = sizeof(ip6_header_t) + sizeof(udp_header_t);
+
+ vlib_buffer_advance(b0, -advance);
+
+ u8 *outer_ptr0 = vlib_buffer_get_current (b0);
+ u8 outer_v0 = *outer_ptr0 & 0xf0;
+
+ ip46_address_t src0 = {0};
+ ip46_address_t dst0 = {0};
+ udp_header_t * udp0 = NULL;
+
+ ip46_address_set_ip6(&src0, &((ip6_header_t *)outer_ptr0)->src_address);
+ ip46_address_set_ip6(&dst0, &((ip6_header_t *)outer_ptr0)->dst_address);
+ udp0 = (udp_header_t *)(outer_ptr0 + sizeof(ip6_header_t));
+ next0 = v0 == 0x40? UDP6_DECAP_NEXT_LOOKUP_IP4 : UDP6_DECAP_NEXT_LOOKUP_IP6;
+
+ hicn_buffer_t *hicnb0 = hicn_get_buffer(b0);
+
+ vnet_buffer (b0)->ip.adj_index[VLIB_RX] = udp_tunnel_get(&dst0, &src0, udp0->dst_port, udp0->src_port);
+
+ if (vnet_buffer (b0)->ip.adj_index[VLIB_RX] !=
+ UDP_TUNNEL_INVALID)
+ hicnb0->flags |= (outer_v0 == 0x40? HICN_BUFFER_FLAGS_FROM_UDP4_TUNNEL : HICN_BUFFER_FLAGS_FROM_UDP6_TUNNEL);
+
+ udp_decap_trace_buffer (vm, node, 0, b0);
+
+ vlib_buffer_advance(b0, advance);
+
+ 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);
+ }
+
+ return (frame->n_vectors);
+}
+
+
+/*
+ * Node registration for the interest forwarder node
+ */
+/* *INDENT-OFF* */
+VLIB_REGISTER_NODE(udp6_decap_node) =
+{
+ .function = udp6_decap_node_fn,
+ .name = "udp6-decap",
+ .vector_size = sizeof(u32),
+ .format_trace = format_udp_decap_trace,
+ .type = VLIB_NODE_TYPE_INTERNAL,
+ .n_errors = ARRAY_LEN(udp_decap_error_strings),
+ .error_strings = udp_decap_error_strings,
+ .n_next_nodes = UDP6_DECAP_N_NEXT,
+ /* edit / add dispositions here */
+ .next_nodes =
+ {
+ [UDP6_DECAP_NEXT_LOOKUP_IP4] = "ip4-lookup",
+ [UDP6_DECAP_NEXT_LOOKUP_IP6] = "ip6-lookup"
+ },
+};
+/* *INDENT-ON* */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/hicn-plugin/src/udp_tunnels/udp_tunnel.c b/hicn-plugin/src/udp_tunnels/udp_tunnel.c
new file mode 100644
index 000000000..872e4cd82
--- /dev/null
+++ b/hicn-plugin/src/udp_tunnels/udp_tunnel.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2020 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 <vppinfra/bihash_40_8.h>
+#include <vnet/fib/fib_table.h>
+
+#include "../error.h"
+#include "../strategy_dpo_ctx.h"
+#include "udp_tunnel.h"
+
+clib_bihash_40_8_t udp_tunnels_hashtb;
+dpo_type_t dpo_type_udp_ip4;
+dpo_type_t dpo_type_udp_ip6;
+
+u32 udp_tunnel_add (fib_protocol_t proto,
+ index_t fib_index,
+ const ip46_address_t * src_ip,
+ const ip46_address_t * dst_ip,
+ u16 src_port,
+ u16 dst_port,
+ udp_encap_fixup_flags_t flags)
+{
+ vlib_main_t *vm = vlib_get_main();
+ clib_bihash_kv_40_8_t kv;
+ clib_memcpy(&kv.key[0], src_ip, sizeof(ip46_address_t));
+ clib_memcpy(&kv.key[2], dst_ip, sizeof(ip46_address_t));
+ kv.key[4] = (clib_host_to_net_u16(src_port) << 16) + clib_host_to_net_u16(dst_port);
+
+ clib_bihash_kv_40_8_t value;
+ int rv = clib_bihash_search_40_8 (&udp_tunnels_hashtb, &kv, &value);
+
+ if (rv != 0)
+ {
+ u32 uei = udp_encap_add_and_lock(proto, fib_index, src_ip, dst_ip, src_port, dst_port, flags);
+ kv.value = uei;
+ clib_bihash_add_del_40_8(&udp_tunnels_hashtb, &kv, 1);
+ value.value = kv.value;
+ if (proto == FIB_PROTOCOL_IP4)
+ {
+ udp_register_dst_port(vm, src_port, udp4_decap_node.index, 1);
+ }
+ else
+ {
+ udp_register_dst_port(vm, src_port, udp6_decap_node.index, 0);
+ }
+ }
+
+ return value.value;
+}
+
+void udp_tunnel_add_existing (index_t uei, dpo_proto_t proto)
+{
+ vlib_main_t *vm = vlib_get_main();
+ udp_encap_t * udp_encap = udp_encap_get(uei);
+ clib_bihash_kv_40_8_t kv;
+
+ ip46_address_t src = {0};
+ ip46_address_t dst = {0};
+ u16 src_port = 0, dst_port = 0;
+
+ switch (proto)
+ {
+ case DPO_PROTO_IP4:
+ ip46_address_set_ip4(&src, &(udp_encap->ue_hdrs.ip4.ue_ip4.src_address));
+ ip46_address_set_ip4(&dst, &(udp_encap->ue_hdrs.ip4.ue_ip4.dst_address));
+ src_port = udp_encap->ue_hdrs.ip4.ue_udp.src_port;
+ dst_port = udp_encap->ue_hdrs.ip4.ue_udp.dst_port;
+ break;
+ case DPO_PROTO_IP6:
+ ip46_address_set_ip6(&src, &(udp_encap->ue_hdrs.ip6.ue_ip6.src_address));
+ ip46_address_set_ip6(&dst, &(udp_encap->ue_hdrs.ip6.ue_ip6.dst_address));
+ src_port = udp_encap->ue_hdrs.ip6.ue_udp.src_port;
+ dst_port = udp_encap->ue_hdrs.ip6.ue_udp.dst_port;
+ break;
+ default:
+ break;
+ }
+
+ clib_memcpy(&kv.key[0], &src, sizeof(ip46_address_t));
+ clib_memcpy(&kv.key[2], &dst, sizeof(ip46_address_t));
+ kv.key[4] = (src_port << 16) + dst_port ;
+ kv.value = uei;
+
+ clib_bihash_add_del_40_8(&udp_tunnels_hashtb, &kv, 1);
+
+ if (proto == DPO_PROTO_IP4)
+ {
+ udp_register_dst_port(vm, clib_net_to_host_u16(src_port), udp4_decap_node.index, 1);
+ }
+ else
+ {
+ udp_register_dst_port(vm, clib_net_to_host_u16(src_port), udp6_decap_node.index, 0);
+ }
+}
+
+int udp_tunnel_del (fib_protocol_t proto,
+ index_t fib_index,
+ const ip46_address_t * src_ip,
+ const ip46_address_t * dst_ip,
+ u16 src_port,
+ u16 dst_port,
+ udp_encap_fixup_flags_t flags)
+{
+ clib_bihash_kv_40_8_t kv;
+ clib_memcpy(&kv.key[0], src_ip, sizeof(ip46_address_t));
+ clib_memcpy(&kv.key[2], dst_ip, sizeof(ip46_address_t));
+ kv.key[4] = (clib_host_to_net_u16(src_port) << 16) + clib_host_to_net_u16(dst_port);
+
+ clib_bihash_kv_40_8_t value;
+ int ret = clib_bihash_search_40_8 (&udp_tunnels_hashtb, &kv, &value);
+
+ if (ret == 0)
+ {
+ udp_encap_unlock((u32)value.value);
+ clib_bihash_add_del_40_8(&udp_tunnels_hashtb, &kv, 0);
+ ret = HICN_ERROR_NONE;
+ }
+ else
+ {
+ ret = HICN_ERROR_UDP_TUNNEL_NOT_FOUND;
+ }
+
+ return ret;
+}
+
+u32 udp_tunnel_get(const ip46_address_t * src_ip,
+ const ip46_address_t * dst_ip,
+ u16 src_port,
+ u16 dst_port)
+{
+ clib_bihash_kv_40_8_t kv;
+ clib_memcpy(&kv.key[0], src_ip, sizeof(ip46_address_t));
+ clib_memcpy(&kv.key[2], dst_ip, sizeof(ip46_address_t));
+ kv.key[4] = (src_port << 16) + dst_port;
+
+ clib_bihash_kv_40_8_t value;
+ int ret = clib_bihash_search_40_8 (&udp_tunnels_hashtb, &kv, &value);
+
+ return ret == 0 ? (u32)value.value : UDP_TUNNEL_INVALID;
+}
+
+
+void udp_tunnel_init()
+{
+ clib_bihash_init_40_8(&udp_tunnels_hashtb, "udp encap table",
+ 2048, 256 << 20);
+
+ /*
+ * Udp encap does not expose the dpo type when it registers.
+ * In the following we understand what is the dpo type for a udp_encap dpo.
+ */
+ ip46_address_t src = {0};
+ ip46_address_t dst = {0};
+
+ src.ip6.as_u8[15] = 1;
+ dst.ip6.as_u8[15] = 2;
+
+ u32 fib_index = fib_table_find (FIB_PROTOCOL_IP6, HICN_FIB_TABLE);
+ u32 uei = udp_encap_add_and_lock(FIB_PROTOCOL_IP6, fib_index, &src, &dst, 4444, 4444, UDP_ENCAP_FIXUP_NONE);
+
+ dpo_id_t temp = DPO_INVALID;
+ udp_encap_contribute_forwarding(uei, DPO_PROTO_IP6, &temp);
+ dpo_type_udp_ip6 = temp.dpoi_type;
+ udp_encap_unlock(uei);
+
+ dpo_id_t temp2 = DPO_INVALID;
+ fib_index = fib_table_find (FIB_PROTOCOL_IP4, HICN_FIB_TABLE);
+ uei = udp_encap_add_and_lock(FIB_PROTOCOL_IP4, fib_index, &src, &dst, 4444, 4444, UDP_ENCAP_FIXUP_NONE);
+ udp_encap_contribute_forwarding(uei, DPO_PROTO_IP4, &temp2);
+ dpo_type_udp_ip4 = temp2.dpoi_type;
+ udp_encap_unlock(uei);
+}
+
+static clib_error_t *
+udp_tunnel_command_fn (vlib_main_t * vm,
+ unformat_input_t * main_input,
+ vlib_cli_command_t * cmd)
+{
+ unformat_input_t _line_input, *line_input = &_line_input;
+ clib_error_t *error = NULL;
+ ip46_address_t src_ip = {0}, dst_ip = {0};
+ u32 table_id, src_port, dst_port;
+ fib_protocol_t fproto;
+ u8 is_del;
+ index_t uei;
+
+ is_del = 0;
+ fproto = FIB_PROTOCOL_MAX;
+ uei = ~0;
+ table_id = HICN_FIB_TABLE;
+
+ /* Get a line of input. */
+ if (unformat_user (main_input, unformat_line_input, line_input))
+ {
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "index %d", &uei))
+ ;
+ else if (unformat (line_input, "add"))
+ is_del = 0;
+ else if (unformat (line_input, "del"))
+ is_del = 1;
+ else if (unformat (line_input, "%U %U",
+ unformat_ip4_address,
+ &src_ip.ip4, unformat_ip4_address, &dst_ip.ip4))
+ fproto = FIB_PROTOCOL_IP4;
+ else if (unformat (line_input, "%U %U",
+ unformat_ip6_address,
+ &src_ip.ip6, unformat_ip6_address, &dst_ip.ip6))
+ fproto = FIB_PROTOCOL_IP6;
+ else if (unformat (line_input, "%d %d", &src_port, &dst_port))
+ ;
+ else if (unformat (line_input, "table-id %d", &table_id))
+ ;
+ else
+ {
+ error = unformat_parse_error (line_input);
+ goto done;
+ }
+ }
+ }
+
+ index_t fib_index = fib_table_find (fproto, table_id);
+ if (~0 == fib_index)
+ {
+ error = clib_error_return (0, "Nonexistent table id %d", table_id);
+ goto done;
+ }
+
+ if (!is_del && fproto != FIB_PROTOCOL_MAX)
+ {
+ uei = udp_tunnel_add(fproto, fib_index, &src_ip, &dst_ip, src_port, dst_port, UDP_ENCAP_FIXUP_NONE);
+
+ vlib_cli_output (vm, "udp-encap: %d\n", uei);
+ }
+ else if (is_del)
+ {
+ int ret = udp_tunnel_del(fproto, fib_index, &src_ip, &dst_ip, src_port, dst_port, UDP_ENCAP_FIXUP_NONE);
+ error = (ret == HICN_ERROR_NONE) ? 0 : clib_error_return (0, "%s\n",
+ get_error_string
+ (ret));
+ }
+ else
+ {
+ error = clib_error_return (0, "specify some IP addresses");
+ }
+
+ done:
+ unformat_free (line_input);
+ return error;
+
+}
+
+/* *INDENT-OFF* */
+VLIB_CLI_COMMAND (udp_tunnel_command, static) =
+ {
+ .path = "udp tunnel",
+ .short_help = "udp tunnel [add/del] src_address dst_address src_port dst_port",
+ .function = udp_tunnel_command_fn,
+ };
+/* *INDENT-ON* */
+
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables: eval: (c-set-style "gnu") End:
+ */
diff --git a/hicn-plugin/src/udp_tunnels/udp_tunnel.h b/hicn-plugin/src/udp_tunnels/udp_tunnel.h
new file mode 100644
index 000000000..2ec92056c
--- /dev/null
+++ b/hicn-plugin/src/udp_tunnels/udp_tunnel.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2020 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 __UDP_TUNNEL__
+#define __UDP_TUNNEL__
+
+#include <vlib/vlib.h>
+#include <vppinfra/error.h>
+#include <vnet/udp/udp_encap.h>
+
+/**
+ * @file udp_tunnel.h
+ *
+ * This file implements bidirectional udp tunnels. Udp tunnels exploit
+ * the udp encap functionality in vpp. In particular, a udp tunnel creates
+ * an udp encap object with the information for encapsulating packets and it
+ * implements the udp decap node. The udp decap node checks if a udp tunnel exists
+ * before performing the decapsulation. If the tunnel does not exist the packet
+ * is dropped.
+ */
+
+#define UDP_TUNNEL_INVALID ~0
+
+extern dpo_type_t dpo_type_udp_ip4;
+extern dpo_type_t dpo_type_udp_ip6;
+
+extern vlib_node_registration_t udp4_decap_node;
+extern vlib_node_registration_t udp6_decap_node;
+
+/**
+ * @brief Create a udp tunnel
+ *
+ * @param proto FIB_PROTOCOL_IP4 or FIB_PROTOCOL_IP6
+ * @param fib_index fib index to add to the udp encap
+ * @param src_ip source address of the tunnel
+ * @param dst_ip destination address of the tunnel
+ * @param src_port source port
+ * @param src_port destination port
+ * @param flags flags for the udp encap
+ *
+ * @return return the id of the tunnel
+ */
+u32 udp_tunnel_add (fib_protocol_t proto,
+ index_t fib_index,
+ const ip46_address_t * src_ip,
+ const ip46_address_t * dst_ip,
+ u16 src_port,
+ u16 dst_port,
+ udp_encap_fixup_flags_t flags);
+
+/**
+ * @brief Retrieve the index of a udp tunnel (same id of the udp encap)
+ *
+ * @param src_ip source address of the tunnel
+ * @param dst_ip destination address of the tunnel
+ * @param src_port source port
+ * @param src_port destination port
+ *
+ * @return id of the udp tunnel/encap
+ */
+u32 udp_tunnel_get(const ip46_address_t * src_ip,
+ const ip46_address_t * dst_ip,
+ u16 src_port,
+ u16 dst_port);
+
+/**
+ * @brief Delete a udp tunnel
+ *
+ * @param proto FIB_PROTOCOL_IP4 or FIB_PROTOCOL_IP6
+ * @param fib_index fib index to add to the udp encap
+ * @param src_ip source address of the tunnel
+ * @param dst_ip destination address of the tunnel
+ * @param src_port source port
+ * @param src_port destination port
+ * @param flags flags for the udp encap
+ *
+ * @return HICN_ERROR_UDP_TUNNEL_NOT_FOUND if the tunnel was not found
+ * or HICN_ERROR_NONE if the tunnel has been deleted
+ */
+int udp_tunnel_del (fib_protocol_t proto,
+ index_t fib_index,
+ const ip46_address_t * src_ip,
+ const ip46_address_t * dst_ip,
+ u16 src_port,
+ u16 dst_port,
+ udp_encap_fixup_flags_t flags);
+
+/**
+ * @brief Add a udp tunnel from an existing udp encap
+ *
+ * @param uei index of the udp encap object
+ * @param proto DPO_PROTO_IP6 or DPO_PROTO_IP4
+ */
+void udp_tunnel_add_existing (index_t uei, dpo_proto_t proto);
+
+/**
+ * @brief Init the udp tunnel module
+ *
+ */
+void udp_tunnel_init();
+
+#endif
diff --git a/hicn-plugin/src/utils.h b/hicn-plugin/src/utils.h
index ecad47e9b..689942ab6 100644
--- a/hicn-plugin/src/utils.h
+++ b/hicn-plugin/src/utils.h
@@ -18,6 +18,17 @@
#include "hicn.h"
+/**
+ * @file
+ *
+ * Helpers to print hicn headers
+ */
+
+/**
+ * @Brief Print the hicn name
+ *
+ * @param name hicn name to print
+ */
always_inline void
hicn_print_name6 (hicn_name_t * name)
{
@@ -29,6 +40,11 @@ hicn_print_name6 (hicn_name_t * name)
printf ("%s\n", s0);
}
+/**
+ * @Brief Print the ipv6 hicn header (src and dst address and port)
+ *
+ * @param hicn0 hICN header to print
+ */
always_inline void
hicn_print6 (hicn_header_t * hicn0)
{
@@ -43,6 +59,11 @@ hicn_print6 (hicn_header_t * hicn0)
vlib_cli_output (vm, "%s\n", s0);
}
+/**
+ * @Brief Print the ipv4 hicn header (src and dst address and port)
+ *
+ * @param hicn0 hICN header to print
+ */
always_inline void
hicn_print4 (hicn_header_t * hicn0)
{
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 3cc40bb7f..0512b7c64 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -48,5 +48,4 @@ endif ()
add_subdirectory(includes)
add_subdirectory (src)
-add_subdirectory (doc)
diff --git a/lib/includes/hicn/ops.h b/lib/includes/hicn/ops.h
index 47795efd5..e8feff92d 100644
--- a/lib/includes/hicn/ops.h
+++ b/lib/includes/hicn/ops.h
@@ -106,6 +106,22 @@ typedef struct hicn_ops_s
const hicn_name_suffix_t * suffix);
/**
+ * @brief Set flag to mark current packet as interest
+ * @param [in] type - hICN packet type
+ * @param [in,out] h - Buffer holding the Interest packet
+ * @return hICN error code
+ */
+ int (*mark_packet_as_interest) (hicn_type_t type, hicn_protocol_t * h);
+
+ /**
+ * @brief Set flag to mark current packet as data
+ * @param [in] type - hICN packet type
+ * @param [in,out] h - Buffer holding the Interest packet
+ * @return hICN error code
+ */
+ int (*mark_packet_as_data) (hicn_type_t type, hicn_protocol_t * h);
+
+ /**
* @brief Clear the necessary Interest fields in order to hash it
* @param [in] type - hICN packet type
* @param [in,out] h - Buffer holding the Interest packet
@@ -438,6 +454,8 @@ typedef struct hicn_ops_s
ATTR_INIT(set_interest_name, protocol ## _set_interest_name), \
ATTR_INIT(get_interest_name_suffix, protocol ## _get_interest_name_suffix), \
ATTR_INIT(set_interest_name_suffix, protocol ## _set_interest_name_suffix), \
+ ATTR_INIT(mark_packet_as_interest, protocol ## _mark_packet_as_interest), \
+ ATTR_INIT(mark_packet_as_data, protocol ## _mark_packet_as_data), \
ATTR_INIT(reset_interest_for_hash, protocol ## _reset_interest_for_hash), \
ATTR_INIT(get_data_locator, protocol ## _get_data_locator), \
ATTR_INIT(set_data_locator, protocol ## _set_data_locator), \
@@ -537,6 +555,12 @@ PAYLOAD (hicn_type_t type, const hicn_protocol_t * h)
#define DECLARE_set_interest_name_suffix(protocol, error) \
int protocol ## _set_interest_name_suffix(hicn_type_t type, hicn_protocol_t * h, const hicn_name_suffix_t * suffix) { return HICN_LIB_ERROR_ ## error ; }
+#define DECLARE_mark_packet_as_interest(protocol, error) \
+ int protocol ## _mark_packet_as_interest(hicn_type_t type, hicn_protocol_t * h) { return HICN_LIB_ERROR_ ## error ; }
+
+#define DECLARE_mark_packet_as_data(protocol, error) \
+ int protocol ## _mark_packet_as_data(hicn_type_t type, hicn_protocol_t * h) { return HICN_LIB_ERROR_ ## error ; }
+
#define DECLARE_reset_interest_for_hash(protocol, error) \
int protocol ## _reset_interest_for_hash(hicn_type_t type, hicn_protocol_t * h) { return HICN_LIB_ERROR_ ## error ; }
diff --git a/lib/includes/hicn/protocol/tcp.h b/lib/includes/hicn/protocol/tcp.h
index ded9a06b2..347682299 100644
--- a/lib/includes/hicn/protocol/tcp.h
+++ b/lib/includes/hicn/protocol/tcp.h
@@ -128,8 +128,6 @@ typedef struct
static_assert (EXPECTED_TCP_HDRLEN == TCP_HDRLEN,
"Size of TCP struct does not match its expected size.");
-#ifndef HICN_VPP_PLUGIN
-
/* TCP flags bit 0 first. */
#define foreach_tcp_flag \
_ (FIN) /**< No more data from sender. */ \
@@ -156,12 +154,6 @@ enum
#undef _
};
-#endif /* HICN_VPP_PLUGIN */
-
-// get_data_name_suffix
-// name->ip4.suffix = h->v4.tcp.seq;
-
-
#endif /* HICN_PROTOCOL_TCP_H */
/*
diff --git a/lib/src/ops.c b/lib/src/ops.c
index 9bb78be65..d49138398 100644
--- a/lib/src/ops.c
+++ b/lib/src/ops.c
@@ -40,6 +40,8 @@ DECLARE_get_interest_name (none, NONE);
DECLARE_set_interest_name (none, NONE);
DECLARE_get_interest_name_suffix (none, NONE);
DECLARE_set_interest_name_suffix (none, NONE);
+DECLARE_mark_packet_as_interest (none, NONE);
+DECLARE_mark_packet_as_data (none, NONE);
DECLARE_reset_interest_for_hash (none, NONE);
DECLARE_get_data_locator (none, NONE);
DECLARE_set_data_locator (none, NONE);
diff --git a/lib/src/protocol/ah.c b/lib/src/protocol/ah.c
index c2f3f552a..da08d1ee8 100644
--- a/lib/src/protocol/ah.c
+++ b/lib/src/protocol/ah.c
@@ -31,6 +31,8 @@ DECLARE_get_interest_name (ah, UNEXPECTED);
DECLARE_set_interest_name (ah, UNEXPECTED);
DECLARE_get_interest_name_suffix (ah, UNEXPECTED);
DECLARE_set_interest_name_suffix (ah, UNEXPECTED);
+DECLARE_mark_packet_as_interest (ah, UNEXPECTED)
+DECLARE_mark_packet_as_data (ah, UNEXPECTED)
DECLARE_get_data_locator (ah, UNEXPECTED);
DECLARE_set_data_locator (ah, UNEXPECTED);
DECLARE_get_data_name (ah, UNEXPECTED);
diff --git a/lib/src/protocol/icmp.c b/lib/src/protocol/icmp.c
index 85605a2c3..b24c0f11e 100644
--- a/lib/src/protocol/icmp.c
+++ b/lib/src/protocol/icmp.c
@@ -25,6 +25,8 @@ DECLARE_get_interest_name (icmp, UNEXPECTED)
DECLARE_set_interest_name (icmp, UNEXPECTED)
DECLARE_get_interest_name_suffix (icmp, UNEXPECTED)
DECLARE_set_interest_name_suffix (icmp, UNEXPECTED)
+DECLARE_mark_packet_as_interest (icmp, UNEXPECTED)
+DECLARE_mark_packet_as_data (icmp, UNEXPECTED)
DECLARE_get_data_locator (icmp, UNEXPECTED)
DECLARE_set_data_locator (icmp, UNEXPECTED)
DECLARE_get_data_name (icmp, UNEXPECTED)
diff --git a/lib/src/protocol/ipv4.c b/lib/src/protocol/ipv4.c
index d8d958350..781907231 100644
--- a/lib/src/protocol/ipv4.c
+++ b/lib/src/protocol/ipv4.c
@@ -109,6 +109,18 @@ ipv4_set_interest_name_suffix (hicn_type_t type, hicn_protocol_t * h,
}
int
+ipv4_mark_packet_as_interest (hicn_type_t type, hicn_protocol_t * h)
+{
+ return CHILD_OPS (mark_packet_as_interest, type, h);
+}
+
+int
+ipv4_mark_packet_as_data (hicn_type_t type, hicn_protocol_t * h)
+{
+ return CHILD_OPS (mark_packet_as_data, type, h);
+}
+
+int
ipv4_reset_interest_for_hash (hicn_type_t type, hicn_protocol_t * h)
{
/* Sets everything to 0 up to IP destination address */
diff --git a/lib/src/protocol/ipv6.c b/lib/src/protocol/ipv6.c
index 622355294..f23b01cd8 100644
--- a/lib/src/protocol/ipv6.c
+++ b/lib/src/protocol/ipv6.c
@@ -99,6 +99,18 @@ ipv6_set_interest_name_suffix (hicn_type_t type, hicn_protocol_t * h,
}
int
+ipv6_mark_packet_as_interest (hicn_type_t type, hicn_protocol_t * h)
+{
+ return CHILD_OPS (mark_packet_as_interest, type, h);
+}
+
+int
+ipv6_mark_packet_as_data (hicn_type_t type, hicn_protocol_t * h)
+{
+ return CHILD_OPS (mark_packet_as_data, type, h);
+}
+
+int
ipv6_reset_interest_for_hash (hicn_type_t type, hicn_protocol_t * h)
{
/* Sets everything to 0 up to IP destination address */
diff --git a/lib/src/protocol/tcp.c b/lib/src/protocol/tcp.c
index 0e3155020..31c495ff4 100644
--- a/lib/src/protocol/tcp.c
+++ b/lib/src/protocol/tcp.c
@@ -83,6 +83,20 @@ tcp_set_interest_name_suffix (hicn_type_t type, hicn_protocol_t * h,
}
int
+tcp_mark_packet_as_interest (hicn_type_t type, hicn_protocol_t * h)
+{
+ h->tcp.flags &= ~HICN_TCP_FLAG_ECE;
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
+tcp_mark_packet_as_data (hicn_type_t type, hicn_protocol_t * h)
+{
+ h->tcp.flags |= HICN_TCP_FLAG_ECE;
+ return HICN_LIB_ERROR_NONE;
+}
+
+int
tcp_reset_interest_for_hash (hicn_type_t type, hicn_protocol_t * h)
{
memset (&(h->tcp), 0, 4);
diff --git a/libtransport/src/core/hicn_forwarder_interface.cc b/libtransport/src/core/hicn_forwarder_interface.cc
index 810daba3a..5a0faa360 100644
--- a/libtransport/src/core/hicn_forwarder_interface.cc
+++ b/libtransport/src/core/hicn_forwarder_interface.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
diff --git a/libtransport/src/core/hicn_forwarder_interface.h b/libtransport/src/core/hicn_forwarder_interface.h
index 6969f4a6b..c4138c6c2 100644
--- a/libtransport/src/core/hicn_forwarder_interface.h
+++ b/libtransport/src/core/hicn_forwarder_interface.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
diff --git a/libtransport/src/core/hicn_vapi.c b/libtransport/src/core/hicn_vapi.c
index d19e36346..be556f3aa 100644
--- a/libtransport/src/core/hicn_vapi.c
+++ b/libtransport/src/core/hicn_vapi.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -18,7 +18,6 @@
#ifdef __vpp__
#include <hicn/transport/utils/log.h>
-
#include <core/hicn_vapi.h>
#define HICN_VPP_PLUGIN
@@ -31,10 +30,10 @@
#include <vlibmemory/api.h>
#include <vppinfra/error.h>
-#include <vnet/fib/fib_types.h>
#include <vnet/ip/format.h>
#include <vnet/ip/ip4_packet.h>
#include <vnet/ip/ip6_packet.h>
+#include <vapi/ip.api.vapi.h>
#include <vapi/hicn.api.vapi.h>
#include <vpp_plugins/hicn/error.h>
@@ -54,6 +53,7 @@ u8 *format_vl_api_address_union(u8 *s, va_list *args) { return NULL; }
/*********************************************************************************/
DEFINE_VAPI_MSG_IDS_HICN_API_JSON
+DEFINE_VAPI_MSG_IDS_IP_API_JSON
static vapi_error_e register_prod_app_cb(
vapi_ctx_t ctx, void *callback_ctx, vapi_error_e rv, bool is_last,
@@ -184,7 +184,7 @@ int hicn_vapi_face_cons_del(vapi_ctx_t ctx,
static vapi_error_e reigster_route_cb(
vapi_ctx_t ctx, void *callback_ctx, vapi_error_e rv, bool is_last,
- vapi_payload_hicn_api_route_nhops_add_reply *reply) {
+ vapi_payload_ip_route_add_del_reply *reply) {
if (reply == NULL) return rv;
return reply->retval;
@@ -193,17 +193,36 @@ static vapi_error_e reigster_route_cb(
int hicn_vapi_register_route(vapi_ctx_t ctx,
hicn_producer_set_route_params *input_params) {
vapi_lock();
- vapi_msg_hicn_api_route_nhops_add *msg =
- vapi_alloc_hicn_api_route_nhops_add(ctx);
+ vapi_msg_ip_route_add_del *msg = vapi_alloc_ip_route_add_del(ctx, 1);
+
+ msg->payload.is_add = 1;
+ if (ip46_address_is_ip4((ip46_address_t *)(input_params->prod_addr))) {
+ memcpy(&msg->payload.route.prefix.address.un.ip4, &input_params->prefix->address.v4,
+ sizeof(ip4_address_t));
+ msg->payload.route.prefix.address.af = ADDRESS_IP4;
+ msg->payload.route.prefix.len = input_params->prefix->len;
+ } else {
+ memcpy(&msg->payload.route.prefix.address.un.ip6, &input_params->prefix->address.v6,
+ sizeof(ip6_address_t));
+ msg->payload.route.prefix.address.af = ADDRESS_IP6;
+ msg->payload.route.prefix.len = input_params->prefix->len;
+ }
+
+ msg->payload.route.paths[0].sw_if_index = ~0;
+ msg->payload.route.paths[0].table_id = 0;
+ if (ip46_address_is_ip4((ip46_address_t *)(input_params->prod_addr))) {
+ memcpy(&(msg->payload.route.paths[0].nh.address.ip4), input_params->prod_addr->v4.as_u8, sizeof(ip4_address_t));
+ msg->payload.route.paths[0].proto = FIB_API_PATH_NH_PROTO_IP4;
+ }
+ else{
+ memcpy(&(msg->payload.route.paths[0].nh.address.ip6), input_params->prod_addr->v6.as_u8, sizeof(ip6_address_t));
+ msg->payload.route.paths[0].proto = FIB_API_PATH_NH_PROTO_IP6;
+ }
- fib_prefix_t prefix;
- memcpy(&prefix.fp_addr, &input_params->prefix->address,
- sizeof(ip46_address_t));
- prefix.fp_len = input_params->prefix->len;
- msg->payload.face_ids[0] = input_params->face_id;
- msg->payload.n_faces = 1;
+ msg->payload.route.paths[0].type = FIB_API_PATH_FLAG_NONE;
+ msg->payload.route.paths[0].flags = FIB_API_PATH_FLAG_NONE;
- int ret = vapi_hicn_api_route_nhops_add(ctx, msg, reigster_route_cb, NULL);
+ int ret = vapi_ip_route_add_del(ctx, msg, reigster_route_cb, NULL);
vapi_unlock();
return ret;
diff --git a/libtransport/src/core/hicn_vapi.h b/libtransport/src/core/hicn_vapi.h
index f2718e6f5..f5d61e7ef 100644
--- a/libtransport/src/core/hicn_vapi.h
+++ b/libtransport/src/core/hicn_vapi.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2017-2020 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:
@@ -20,6 +20,8 @@
#ifdef __vpp__
+
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -57,7 +59,7 @@ typedef struct {
typedef struct {
ip_prefix_t* prefix;
- uint32_t face_id;
+ ip_address_t* prod_addr;
} hicn_producer_set_route_params;
int hicn_vapi_register_prod_app(
diff --git a/libtransport/src/core/vpp_forwarder_interface.cc b/libtransport/src/core/vpp_forwarder_interface.cc
index 7b4298592..28a2560b3 100644
--- a/libtransport/src/core/vpp_forwarder_interface.cc
+++ b/libtransport/src/core/vpp_forwarder_interface.cc
@@ -167,7 +167,7 @@ void VPPForwarderInterface::registerRoute(Prefix &prefix) {
params.prefix->address = addr.address;
params.prefix->family = addr.family;
params.prefix->len = addr.len;
- params.face_id = face_id1_;
+ params.prod_addr = &producer_locator;
int ret = hicn_vapi_register_route(VPPForwarderInterface::sock_, &params);
diff --git a/libtransport/src/core/vpp_forwarder_interface.h b/libtransport/src/core/vpp_forwarder_interface.h
index eb759f8bc..bc83f476e 100644
--- a/libtransport/src/core/vpp_forwarder_interface.h
+++ b/libtransport/src/core/vpp_forwarder_interface.h
@@ -21,6 +21,7 @@
#include <hicn/transport/core/prefix.h>
+
#ifdef always_inline
#undef always_inline
#endif
diff --git a/scripts/build-packages.sh b/scripts/build-packages.sh
index a027d059b..5967b63bc 100644
--- a/scripts/build-packages.sh
+++ b/scripts/build-packages.sh
@@ -268,7 +268,7 @@ build_doxygen() {
mkdir -p ${SCRIPT_PATH}/../build-doxygen
pushd ${SCRIPT_PATH}/../build-doxygen
- cmake -DBUILD_HICNPLUGIN=OFF -DBUILD_HICNLIGHT=OFF -DBUILD_LIBTRANSPORT=OFF -DBUILD_UTILS=OFF -DBUILD_APPS=OFF -DBUILD_CTRL=OFF ..
+ cmake -DBUILD_HICNPLUGIN=On -DBUILD_HICNLIGHT=OFF -DBUILD_LIBTRANSPORT=OFF -DBUILD_UTILS=OFF -DBUILD_APPS=OFF -DBUILD_CTRL=OFF ..
make doc
popd
}