aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichele Papalini <micpapal@cisco.com>2022-10-11 08:44:22 +0000
committerMichele Papalini <micpapal@cisco.com>2022-10-11 14:13:40 +0000
commitf4d8a383451074a026ac385e97ec4d03a659cd66 (patch)
tree9428883847bf927285a104aa57254c86da65dc2f
parent03fb1444ad41d254469b4749382d1bf2b7cc48da (diff)
feat(strategy): forwarding strategy for local faces
Ref: HICN-802 Signed-off-by: Michele Papalini <micpapal@cisco.com> Change-Id: I22b48d700b1b46599e570d841932d74c5ac65891
-rw-r--r--ctrl/libhicnctrl/src/commands/command_strategy.c2
-rw-r--r--ctrl/libhicnctrl/src/parse.c1
-rw-r--r--hicn-light/src/hicn/core/nexthops.c6
-rw-r--r--hicn-light/src/hicn/core/nexthops.h1
-rw-r--r--hicn-light/src/hicn/core/strategy_vft.c2
-rw-r--r--hicn-light/src/hicn/strategies/CMakeLists.txt2
-rw-r--r--hicn-light/src/hicn/strategies/local_remote.c105
-rw-r--r--hicn-light/src/hicn/strategies/local_remote.h40
-rw-r--r--hicn-light/src/hicn/test/CMakeLists.txt1
-rw-r--r--hicn-light/src/hicn/test/test-strategy-local-remote.cc241
-rw-r--r--lib/includes/hicn/strategy.h1
11 files changed, 401 insertions, 1 deletions
diff --git a/ctrl/libhicnctrl/src/commands/command_strategy.c b/ctrl/libhicnctrl/src/commands/command_strategy.c
index 5605822e7..f7f5974d1 100644
--- a/ctrl/libhicnctrl/src/commands/command_strategy.c
+++ b/ctrl/libhicnctrl/src/commands/command_strategy.c
@@ -15,7 +15,7 @@
.name = "strategy", \
.help = \
"Strategy type (e.g. 'random', 'loadbalancer', 'low_latency', " \
- "'replication', 'bestpath').", \
+ "'replication', 'bestpath', local_remote).", \
.type = TYPE_ENUM(strategy_type), .offset = offsetof(hc_strategy_t, type), \
}
diff --git a/ctrl/libhicnctrl/src/parse.c b/ctrl/libhicnctrl/src/parse.c
index ca19d8280..25fa98de2 100644
--- a/ctrl/libhicnctrl/src/parse.c
+++ b/ctrl/libhicnctrl/src/parse.c
@@ -382,6 +382,7 @@ const char * cmds[] = {
"set strategy b001::/16 low_latency",
"set strategy b001::/16 replication",
"set strategy b001::/16 bestpath",
+ "set strategy b001::/16 local_remote",
"set wldr <on|off> <connection_id>", // on-off vs unset
"cache clear",
"cache store on/off", // set/unset
diff --git a/hicn-light/src/hicn/core/nexthops.c b/hicn-light/src/hicn/core/nexthops.c
index 70089399d..1a6096777 100644
--- a/hicn-light/src/hicn/core/nexthops.c
+++ b/hicn-light/src/hicn/core/nexthops.c
@@ -29,6 +29,12 @@ int nexthops_disable(nexthops_t *nexthops, off_t offset) {
return 0;
}
+int nexthops_disable_all(nexthops_t *nexthops) {
+ nexthops->flags = ~0;
+ nexthops->cur_elts = 0;
+ return 0;
+}
+
void nexthops_reset(nexthops_t *nexthops) {
nexthops->flags = 0;
nexthops->cur_elts = nexthops->num_elts;
diff --git a/hicn-light/src/hicn/core/nexthops.h b/hicn-light/src/hicn/core/nexthops.h
index ff83199a6..232c74388 100644
--- a/hicn-light/src/hicn/core/nexthops.h
+++ b/hicn-light/src/hicn/core/nexthops.h
@@ -94,6 +94,7 @@ typedef struct nexthops_s {
} while (0)
int nexthops_disable(nexthops_t *nexthops, off_t offset);
+int nexthops_disable_all(nexthops_t *nexthops);
#define nexthops_disable_if(NH, i, condition) \
do { \
diff --git a/hicn-light/src/hicn/core/strategy_vft.c b/hicn-light/src/hicn/core/strategy_vft.c
index dcfda5c78..0af035c88 100644
--- a/hicn-light/src/hicn/core/strategy_vft.c
+++ b/hicn-light/src/hicn/core/strategy_vft.c
@@ -25,12 +25,14 @@ extern const strategy_ops_t strategy_random;
extern const strategy_ops_t strategy_replication;
extern const strategy_ops_t strategy_bestpath;
extern const strategy_ops_t strategy_low_latency;
+extern const strategy_ops_t strategy_local_remote;
const strategy_ops_t *const strategy_vft[] = {
[STRATEGY_TYPE_LOADBALANCER] = &strategy_load_balancer,
[STRATEGY_TYPE_RANDOM] = &strategy_random,
[STRATEGY_TYPE_REPLICATION] = &strategy_replication,
[STRATEGY_TYPE_BESTPATH] = &strategy_bestpath,
+ [STRATEGY_TYPE_LOCAL_REMOTE] = &strategy_local_remote,
#if 0
[STRATEGY_TYPE_LOW_LATENCY] = &strategy_low_latency,
#endif
diff --git a/hicn-light/src/hicn/strategies/CMakeLists.txt b/hicn-light/src/hicn/strategies/CMakeLists.txt
index 434106a44..754974ee4 100644
--- a/hicn-light/src/hicn/strategies/CMakeLists.txt
+++ b/hicn-light/src/hicn/strategies/CMakeLists.txt
@@ -18,6 +18,7 @@ list(APPEND HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/best_path.h
${CMAKE_CURRENT_SOURCE_DIR}/local_prefixes.h
${CMAKE_CURRENT_SOURCE_DIR}/probe_generator.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/local_remote.h
)
list(APPEND SOURCE_FILES
@@ -27,6 +28,7 @@ list(APPEND SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/best_path.c
${CMAKE_CURRENT_SOURCE_DIR}/local_prefixes.c
${CMAKE_CURRENT_SOURCE_DIR}/probe_generator.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/local_remote.c
)
set(SOURCE_FILES ${SOURCE_FILES} PARENT_SCOPE)
diff --git a/hicn-light/src/hicn/strategies/local_remote.c b/hicn-light/src/hicn/strategies/local_remote.c
new file mode 100644
index 000000000..7edf62643
--- /dev/null
+++ b/hicn-light/src/hicn/strategies/local_remote.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <hicn/core/nexthops.h>
+#include <hicn/core/forwarder.h>
+
+#include "local_remote.h"
+
+static int strategy_local_remote_initialize(strategy_entry_t *entry,
+ const void *forwarder) {
+ printf("INIT FWD STRATEGY REMOTE LOCAL\n");
+ srand((unsigned int)time(NULL));
+ entry->forwarder = forwarder;
+ return 0;
+}
+
+static int strategy_local_remote_finalize(strategy_entry_t *entry) {
+ /* Nothing to do */
+ return 0;
+}
+
+static int strategy_local_remote_add_nexthop(strategy_entry_t *entry,
+ nexthops_t *nexthops,
+ off_t offset) {
+ /* Nothing to do */
+ return 0;
+}
+
+static int strategy_local_remote_remove_nexthop(strategy_entry_t *entry,
+ nexthops_t *nexthops,
+ off_t offset) {
+ /* Nothing to do */
+ return 0;
+}
+
+static nexthops_t *strategy_local_remote_lookup_nexthops(
+ strategy_entry_t *entry, nexthops_t *nexthops, const msgbuf_t *msgbuf) {
+ if (!entry->forwarder) {
+ // the forwarder does not exists, drop packet
+ nexthops_disable_all(nexthops);
+ return nexthops;
+ }
+
+ unsigned cid = msgbuf_get_connection_id(msgbuf);
+ connection_table_t *table = forwarder_get_connection_table(entry->forwarder);
+ if (!table) {
+ // the connection table does not exists, drop packet.
+ nexthops_disable_all(nexthops);
+ return nexthops;
+ }
+
+ connection_t *in = connection_table_get_by_id(table, cid);
+ if (!in) {
+ // the ingress connection does not exists, drop packet.
+ nexthops_disable_all(nexthops);
+ return nexthops;
+ }
+
+ bool in_is_local = connection_is_local(in);
+ nexthops_enumerate(nexthops, i, nexthop, {
+ connection_t *out = connection_table_get_by_id(table, nexthop);
+ if (out) {
+ if (connection_is_local(out) != in_is_local) {
+ // this connection satisfies the requirements, send the intetest here.
+ nexthops_select(nexthops, i);
+ return nexthops;
+ }
+ }
+ });
+
+ // no out connection satisfies the requirements, drop packet.
+ nexthops_disable_all(nexthops);
+ return nexthops;
+}
+
+static int strategy_local_remote_on_data(strategy_entry_t *entry,
+ nexthops_t *nexthops,
+ const nexthops_t *data_nexthops,
+ const msgbuf_t *msgbuf,
+ Ticks pitEntryCreation,
+ Ticks objReception) {
+ /* Nothing to do */
+ return 0;
+}
+
+static int strategy_local_remote_on_timeout(
+ strategy_entry_t *entry, nexthops_t *nexthops,
+ const nexthops_t *timeout_nexthops) {
+ /* Nothing to do */
+ return 0;
+}
+
+DECLARE_STRATEGY(local_remote);
diff --git a/hicn-light/src/hicn/strategies/local_remote.h b/hicn-light/src/hicn/strategies/local_remote.h
new file mode 100644
index 000000000..58ca5abc3
--- /dev/null
+++ b/hicn-light/src/hicn/strategies/local_remote.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Forward on a single path. If the incoming interest arrives from a local face,
+ * the interest shuold be forwarded only on a remote face. Viceversa, if the
+ * interest comes from remote it should be sent to a local face. Notice that if
+ * the condition cannot be satified (e.g. an interest comes from a local face
+ * and only an other local face can be satified to send the interest) the
+ * interest is dropped
+ */
+
+#ifndef HICNLIGHT_STRATEGY_LOCAL_REMOTE_H
+#define HICNLIGHT_STRATEGY_LOCAL_REMOTE_H
+
+typedef struct {
+ void *_;
+} strategy_loc_rem_nexthop_state_t;
+
+typedef struct {
+ void *_;
+} strategy_loc_rem_state_t;
+
+typedef struct {
+ void *_;
+} strategy_loc_rem_options_t;
+
+#endif /* HICNLIGHT_STRATEGY_LOCAL_REMOTE_H */
diff --git a/hicn-light/src/hicn/test/CMakeLists.txt b/hicn-light/src/hicn/test/CMakeLists.txt
index cbe939297..395b6e333 100644
--- a/hicn-light/src/hicn/test/CMakeLists.txt
+++ b/hicn-light/src/hicn/test/CMakeLists.txt
@@ -17,6 +17,7 @@ list(APPEND TESTS_SRC
test-strategy-random.cc
test-strategy-replication.cc
test-strategy-best-path.cc
+ test-strategy-local-remote.cc
test-subscription.cc
test-local_prefixes.cc
test-probe_generator.cc
diff --git a/hicn-light/src/hicn/test/test-strategy-local-remote.cc b/hicn-light/src/hicn/test/test-strategy-local-remote.cc
new file mode 100644
index 000000000..b6e84d946
--- /dev/null
+++ b/hicn-light/src/hicn/test/test-strategy-local-remote.cc
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2021 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+#include <gmock/gmock.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+extern "C" {
+#define WITH_TESTS
+#include <hicn/base/loop.h>
+#include <hicn/config/configuration.h>
+#include <hicn/core/forwarder.h>
+#include <hicn/core/listener.h>
+#include <hicn/core/address_pair.h>
+#include <hicn/core/address.h>
+#include <hicn/core/strategy.h>
+#include <hicn/strategies/local_remote.h>
+}
+
+class StrategyLocalRemoteTest : public ::testing::Test {
+ protected:
+ StrategyLocalRemoteTest() {
+ conf_ = configuration_create();
+ MAIN_LOOP = loop_create();
+ fwd_ = forwarder_create(conf_);
+
+ /* Strategy and strategy entry */
+ entry_ = {
+ .type = STRATEGY_TYPE_LOCAL_REMOTE,
+ .options =
+ {
+ .random = {},
+ },
+ .state = {.random = {}},
+ };
+
+ strategy_initialize(&entry_, fwd_);
+ }
+
+ virtual ~StrategyLocalRemoteTest() {
+ INFO("loop stopped");
+ forwarder_free(fwd_);
+ loop_free(MAIN_LOOP);
+ MAIN_LOOP = NULL;
+ strategy_finalize(&entry_);
+ }
+
+ strategy_entry_t entry_;
+ nexthops_t available_nexthops_;
+ configuration_t* conf_;
+ forwarder_t* fwd_;
+ msgbuf_t msgbuf_;
+};
+
+TEST_F(StrategyLocalRemoteTest, InputLocalOutputLocal) {
+ address_t listener_addr = ADDRESS4_LOCALHOST(9596);
+ address_t prod_addr = ADDRESS4_LOCALHOST(12345);
+ address_t cons_addr = ADDRESS4_LOCALHOST(54321);
+
+ listener_t* listener = listener_create(FACE_TYPE_UDP_LISTENER, &listener_addr,
+ "lo", "lo_udp4", fwd_);
+
+ address_pair_t pair_conn_prod = {
+ .local = listener_addr,
+ .remote = prod_addr,
+ };
+
+ address_pair_t pair_conn_cons = {
+ .local = listener_addr,
+ .remote = cons_addr,
+ };
+
+ unsigned prod_conn_id =
+ listener_create_connection(listener, "conp", &pair_conn_prod);
+ unsigned cons_conn_id =
+ listener_create_connection(listener, "conc", &pair_conn_cons);
+
+ msgbuf_.connection_id = cons_conn_id;
+
+ nexthops_add(&available_nexthops_, prod_conn_id);
+ nexthops_t* nexthops;
+ nexthops = strategy_lookup_nexthops(&entry_, &available_nexthops_, &msgbuf_);
+
+ EXPECT_EQ(nexthops_get_curlen(nexthops), (size_t)0);
+}
+
+TEST_F(StrategyLocalRemoteTest, InputRemoteOutputRemote) {
+ const char prod_addr_str[] = "192.168.1.1";
+ const char cons_addr_str[] = "192.168.1.2";
+ in_addr_t prod_addr_int;
+ in_addr_t cons_addr_int;
+ inet_pton(AF_INET, prod_addr_str, &prod_addr_int);
+ inet_pton(AF_INET, cons_addr_str, &cons_addr_int);
+
+ address_t prod_addr = ADDRESS4(prod_addr_int, 12345);
+ address_t cons_addr = ADDRESS4(cons_addr_int, 12345);
+ address_t listener_addr = ADDRESS4_LOCALHOST(9596);
+
+ listener_t* listener = listener_create(FACE_TYPE_UDP_LISTENER, &listener_addr,
+ "lo", "lo_udp4", fwd_);
+
+ address_pair_t pair_conn_prod = {
+ .local = listener_addr,
+ .remote = prod_addr,
+ };
+
+ address_pair_t pair_conn_cons = {
+ .local = listener_addr,
+ .remote = cons_addr,
+ };
+
+ connection_t* conn;
+ unsigned prod_conn_id =
+ listener_create_connection(listener, "conp", &pair_conn_prod);
+ unsigned cons_conn_id =
+ listener_create_connection(listener, "conc", &pair_conn_cons);
+
+ // fake two remote connections
+ conn = connection_table_get_by_id(forwarder_get_connection_table(fwd_),
+ prod_conn_id);
+ conn->local = false;
+ conn = connection_table_get_by_id(forwarder_get_connection_table(fwd_),
+ cons_conn_id);
+ conn->local = false;
+
+ msgbuf_.connection_id = cons_conn_id;
+
+ nexthops_add(&available_nexthops_, prod_conn_id);
+ nexthops_t* nexthops;
+ nexthops = strategy_lookup_nexthops(&entry_, &available_nexthops_, &msgbuf_);
+
+ EXPECT_EQ(nexthops_get_curlen(nexthops), (size_t)0);
+}
+
+TEST_F(StrategyLocalRemoteTest, InputLocalOutputRemote) {
+ const char prod_addr_str[] = "192.168.1.1";
+ in_addr_t prod_addr_int;
+ inet_pton(AF_INET, prod_addr_str, &prod_addr_int);
+
+ address_t prod_addr = ADDRESS4(prod_addr_int, 12345);
+ address_t cons_addr = ADDRESS4_LOCALHOST(12345);
+ address_t listener_addr = ADDRESS4_LOCALHOST(9596);
+
+ listener_t* listener = listener_create(FACE_TYPE_UDP_LISTENER, &listener_addr,
+ "lo", "lo_udp4", fwd_);
+
+ address_pair_t pair_conn_prod = {
+ .local = listener_addr,
+ .remote = prod_addr,
+ };
+
+ address_pair_t pair_conn_cons = {
+ .local = listener_addr,
+ .remote = cons_addr,
+ };
+
+ connection_t* conn;
+ unsigned prod_conn_id =
+ listener_create_connection(listener, "conp", &pair_conn_prod);
+ unsigned cons_conn_id =
+ listener_create_connection(listener, "conc", &pair_conn_cons);
+
+ conn = connection_table_get_by_id(forwarder_get_connection_table(fwd_),
+ prod_conn_id);
+ conn->local = false;
+ conn = connection_table_get_by_id(forwarder_get_connection_table(fwd_),
+ cons_conn_id);
+ conn->local = true;
+
+ msgbuf_.connection_id = cons_conn_id;
+
+ nexthops_add(&available_nexthops_, prod_conn_id);
+ nexthops_t* nexthops;
+ nexthops = strategy_lookup_nexthops(&entry_, &available_nexthops_, &msgbuf_);
+
+ EXPECT_EQ(nexthops_get_curlen(nexthops), (size_t)1);
+}
+
+TEST_F(StrategyLocalRemoteTest, InputRemoteOutputLocal) {
+ const char cons_addr_str[] = "192.168.1.2";
+ in_addr_t cons_addr_int;
+ inet_pton(AF_INET, cons_addr_str, &cons_addr_int);
+
+ address_t cons_addr = ADDRESS4(cons_addr_int, 12345);
+ address_t prod_addr = ADDRESS4_LOCALHOST(12345);
+ address_t listener_addr = ADDRESS4_LOCALHOST(9596);
+
+ listener_t* listener = listener_create(FACE_TYPE_UDP_LISTENER, &listener_addr,
+ "lo", "lo_udp4", fwd_);
+
+ address_pair_t pair_conn_prod = {
+ .local = listener_addr,
+ .remote = prod_addr,
+ };
+
+ address_pair_t pair_conn_cons = {
+ .local = listener_addr,
+ .remote = cons_addr,
+ };
+
+ connection_t* conn;
+ unsigned prod_conn_id =
+ listener_create_connection(listener, "conp", &pair_conn_prod);
+ unsigned cons_conn_id =
+ listener_create_connection(listener, "conc", &pair_conn_cons);
+
+ conn = connection_table_get_by_id(forwarder_get_connection_table(fwd_),
+ prod_conn_id);
+ conn->local = true;
+ conn = connection_table_get_by_id(forwarder_get_connection_table(fwd_),
+ cons_conn_id);
+ conn->local = false;
+
+ msgbuf_.connection_id = cons_conn_id;
+
+ nexthops_add(&available_nexthops_, prod_conn_id);
+ nexthops_t* nexthops;
+ nexthops = strategy_lookup_nexthops(&entry_, &available_nexthops_, &msgbuf_);
+
+ EXPECT_EQ(nexthops_get_curlen(nexthops), (size_t)1);
+}
diff --git a/lib/includes/hicn/strategy.h b/lib/includes/hicn/strategy.h
index c71db451a..196d59efa 100644
--- a/lib/includes/hicn/strategy.h
+++ b/lib/includes/hicn/strategy.h
@@ -29,6 +29,7 @@
_ (RANDOM) \
_ (REPLICATION) \
_ (BESTPATH) \
+ _ (LOCAL_REMOTE) \
_ (N)
typedef enum