diff options
author | Michele Papalini <micpapal@cisco.com> | 2022-10-11 14:40:15 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@fd.io> | 2022-10-11 14:40:15 +0000 |
commit | 5ee46ef7ce250a52d85eeafc0dd27de0cd5d6f67 (patch) | |
tree | feb69edecb37ef327bcff0a922f123ceebfc58c2 | |
parent | 0b65acf82a4a1199220d4473d426a9da221e9629 (diff) | |
parent | f4d8a383451074a026ac385e97ec4d03a659cd66 (diff) |
Merge "feat(strategy): forwarding strategy for local faces Ref: HICN-802"
-rw-r--r-- | ctrl/libhicnctrl/src/commands/command_strategy.c | 2 | ||||
-rw-r--r-- | ctrl/libhicnctrl/src/parse.c | 1 | ||||
-rw-r--r-- | hicn-light/src/hicn/core/nexthops.c | 6 | ||||
-rw-r--r-- | hicn-light/src/hicn/core/nexthops.h | 1 | ||||
-rw-r--r-- | hicn-light/src/hicn/core/strategy_vft.c | 2 | ||||
-rw-r--r-- | hicn-light/src/hicn/strategies/CMakeLists.txt | 2 | ||||
-rw-r--r-- | hicn-light/src/hicn/strategies/local_remote.c | 105 | ||||
-rw-r--r-- | hicn-light/src/hicn/strategies/local_remote.h | 40 | ||||
-rw-r--r-- | hicn-light/src/hicn/test/CMakeLists.txt | 1 | ||||
-rw-r--r-- | hicn-light/src/hicn/test/test-strategy-local-remote.cc | 241 | ||||
-rw-r--r-- | lib/includes/hicn/strategy.h | 1 |
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 |