From 0ac147d632ed6a150bf0216964888a21b1c8d43c Mon Sep 17 00:00:00 2001 From: Jordan Augé Date: Tue, 24 Jan 2023 01:46:29 +0100 Subject: feat: libhicnctrl: new API to allow sending MAP-Me command on specific face MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Iac39a1d145a5c1b4f19e1fa35d713ca720393760 Ticket: HICN-832 Signed-off-by: Jordan Augé (cherry picked from commit 49776ceac54eecadabca6c0e2fdc0b9ee2e8e663) --- ctrl/libhicnctrl/includes/hicn/ctrl/api.h | 4 +- ctrl/libhicnctrl/includes/hicn/ctrl/hicn-light.h | 24 ++- .../libhicnctrl/includes/hicn/ctrl/objects/mapme.h | 7 +- ctrl/libhicnctrl/src/CMakeLists.txt | 6 +- ctrl/libhicnctrl/src/commands/command_cache.c | 20 ++ ctrl/libhicnctrl/src/commands/command_connection.c | 19 ++ ctrl/libhicnctrl/src/commands/command_face.c | 19 ++ ctrl/libhicnctrl/src/commands/command_listener.c | 19 ++ ctrl/libhicnctrl/src/commands/command_mapme.c | 19 ++ ctrl/libhicnctrl/src/commands/command_policy.c | 20 ++ ctrl/libhicnctrl/src/commands/command_punting.c | 20 ++ ctrl/libhicnctrl/src/commands/command_route.c | 65 +++++- ctrl/libhicnctrl/src/commands/command_stats.c | 19 ++ ctrl/libhicnctrl/src/commands/command_strategy.c | 19 ++ .../src/commands/command_subscription.c | 19 ++ ctrl/libhicnctrl/src/hicnctrl.c | 9 +- ctrl/libhicnctrl/src/module.h | 22 ++ ctrl/libhicnctrl/src/module_object_vft.h | 4 - ctrl/libhicnctrl/src/modules/CMakeLists.txt | 4 +- ctrl/libhicnctrl/src/modules/hicn_light.c | 12 +- ctrl/libhicnctrl/src/modules/hicn_light/mapme.c | 183 +++++----------- ctrl/libhicnctrl/src/modules/hicn_light/mapme.h | 28 +++ ctrl/libhicnctrl/src/object_private.h | 24 ++- ctrl/libhicnctrl/src/object_vft.c | 28 ++- ctrl/libhicnctrl/src/objects/mapme.c | 95 ++++++++ ctrl/libhicnctrl/src/objects/mapme.h | 30 +++ ctrl/libhicnctrl/src/objects/route.c | 25 ++- hicn-light/src/hicn/config/CMakeLists.txt | 3 +- hicn-light/src/hicn/config/commands.c | 97 +++++++-- hicn-light/src/hicn/core/connection.h | 4 +- hicn-light/src/hicn/core/fib.c | 23 +- hicn-light/src/hicn/core/fib.h | 4 +- hicn-light/src/hicn/core/fib_entry.c | 15 +- hicn-light/src/hicn/core/fib_entry.h | 6 +- hicn-light/src/hicn/core/forwarder.c | 39 +++- hicn-light/src/hicn/core/mapme.c | 238 ++++++++++++++------- hicn-light/src/hicn/core/mapme.h | 29 ++- hicn-light/src/hicn/core/msgbuf.h | 8 +- hicn-light/src/hicn/strategies/local_prefixes.c | 4 +- lib/src/protocol/icmp.c | 5 +- .../io_modules/hicn-light/hicn_forwarder_module.cc | 22 +- 41 files changed, 925 insertions(+), 335 deletions(-) delete mode 100644 ctrl/libhicnctrl/src/module_object_vft.h create mode 100644 ctrl/libhicnctrl/src/modules/hicn_light/mapme.h create mode 100644 ctrl/libhicnctrl/src/objects/mapme.c create mode 100644 ctrl/libhicnctrl/src/objects/mapme.h diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/api.h b/ctrl/libhicnctrl/includes/hicn/ctrl/api.h index ad3f8fcc3..87f0e955d 100644 --- a/ctrl/libhicnctrl/includes/hicn/ctrl/api.h +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Cisco and/or its affiliates. + * Copyright (c) 2021-2023 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: @@ -303,7 +303,7 @@ int hc_mapme_set(hc_sock_t *s, hc_mapme_t *mapme); int hc_mapme_set_discovery(hc_sock_t *s, hc_mapme_t *mapme); int hc_mapme_set_timescale(hc_sock_t *s, hc_mapme_t *mapme); int hc_mapme_set_retx(hc_sock_t *s, hc_mapme_t *mapme); -int hc_mapme_send_update(hc_sock_t *s, hc_mapme_t *mapme); +int hc_mapme_create(hc_sock_t *s, hc_mapme_t *mapme); int hc_policy_create(hc_sock_t *s, hc_policy_t *policy); int hc_policy_delete(hc_sock_t *s, hc_policy_t *policy); diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/hicn-light.h b/ctrl/libhicnctrl/includes/hicn/ctrl/hicn-light.h index 426b82fa9..3e3e98c35 100644 --- a/ctrl/libhicnctrl/includes/hicn/ctrl/hicn-light.h +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/hicn-light.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Copyright (c) 2021-2023 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: @@ -14,14 +14,14 @@ */ /* - * @file commands.h - * @brief All hicn-light commands: 14 in total. + * @file hicn-light.h + * @brief hicn-light specifics. * * Header and payload in binary format. */ -#ifndef HICN_CTRL_HICNLIGHTNG_H -#define HICN_CTRL_HICNLIGHTNG_H +#ifndef HICN_CTRL_HICNLIGHT_H +#define HICN_CTRL_HICNLIGHT_H #ifndef _WIN32 #include @@ -84,7 +84,7 @@ typedef enum { _(mapme_set_discovery, MAPME_SET_DISCOVERY) \ _(mapme_set_timescale, MAPME_SET_TIMESCALE) \ _(mapme_set_retx, MAPME_SET_RETX) \ - _(mapme_send_update, MAPME_SEND_UPDATE) \ + _(mapme_add, MAPME_ADD) \ _(policy_add, POLICY_ADD) \ _(policy_remove, POLICY_REMOVE) \ _(policy_list, POLICY_LIST) \ @@ -301,9 +301,17 @@ typedef struct { typedef cmd_mapme_timing_t cmd_mapme_set_timescale_t; typedef cmd_mapme_timing_t cmd_mapme_set_retx_t; +typedef struct { + hicn_ip_address_t address; + uint32_t face_id; + uint8_t family; + uint8_t len; +} cmd_mapme_add_t; + +/* dummy */ typedef struct { void *_; -} cmd_mapme_send_update_t; +} cmd_mapme_list_item_t; /* Policy */ @@ -538,4 +546,4 @@ ssize_t hc_light_command_serialize(hc_action_t action, int hc_sock_initialize_module(hc_sock_t *s); -#endif /* HICN_CTRL_HICNLIGHTNG_H */ +#endif /* HICN_CTRL_HICNLIGHT_H */ diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/objects/mapme.h b/ctrl/libhicnctrl/includes/hicn/ctrl/objects/mapme.h index 37623ebfe..3eda1bfaa 100644 --- a/ctrl/libhicnctrl/includes/hicn/ctrl/objects/mapme.h +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/objects/mapme.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Copyright (c) 2021-2023 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: @@ -51,8 +51,9 @@ typedef struct { uint32_t timescale; // Milliseconds hicn_ip_address_t address; - int family; - u8 len; + uint8_t family; + uint8_t len; + uint32_t face_id; } hc_mapme_t; #endif /* HICNCTRL_OBJECTS_MAPME_H */ diff --git a/ctrl/libhicnctrl/src/CMakeLists.txt b/ctrl/libhicnctrl/src/CMakeLists.txt index 5dbd70ffe..3ea5c5db9 100644 --- a/ctrl/libhicnctrl/src/CMakeLists.txt +++ b/ctrl/libhicnctrl/src/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2021-2022 Cisco and/or its affiliates. +# Copyright (c) 2021-2023 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,6 +39,7 @@ set(SOURCE_FILES objects/connection.c objects/face.c objects/listener.c + objects/mapme.c objects/route.c objects/strategy.c objects/stats.c @@ -56,6 +57,7 @@ set(HEADER_FILES objects/connection.h objects/face.h objects/listener.h + objects/mapme.h objects/route.h objects/stats.h objects/strategy.h @@ -115,6 +117,7 @@ if (${CMAKE_SYSTEM_NAME} MATCHES Android OR ${CMAKE_SYSTEM_NAME} MATCHES iOS) ${CMAKE_CURRENT_SOURCE_DIR}/modules/hicn_light/connection.c ${CMAKE_CURRENT_SOURCE_DIR}/modules/hicn_light/face.c ${CMAKE_CURRENT_SOURCE_DIR}/modules/hicn_light/listener.c + ${CMAKE_CURRENT_SOURCE_DIR}/modules/hicn_light/mapme.c ${CMAKE_CURRENT_SOURCE_DIR}/modules/hicn_light/route.c ${CMAKE_CURRENT_SOURCE_DIR}/modules/hicn_light/stats.c ${CMAKE_CURRENT_SOURCE_DIR}/modules/hicn_light/strategy.c @@ -124,6 +127,7 @@ if (${CMAKE_SYSTEM_NAME} MATCHES Android OR ${CMAKE_SYSTEM_NAME} MATCHES iOS) ${CMAKE_CURRENT_SOURCE_DIR}/modules/hicn_light/connection.h ${CMAKE_CURRENT_SOURCE_DIR}/modules/hicn_light/face.h ${CMAKE_CURRENT_SOURCE_DIR}/modules/hicn_light/listener.h + ${CMAKE_CURRENT_SOURCE_DIR}/modules/hicn_light/mapme.h ${CMAKE_CURRENT_SOURCE_DIR}/modules/hicn_light/route.h ${CMAKE_CURRENT_SOURCE_DIR}/modules/hicn_light/stats.h ${CMAKE_CURRENT_SOURCE_DIR}/modules/hicn_light/strategy.h diff --git a/ctrl/libhicnctrl/src/commands/command_cache.c b/ctrl/libhicnctrl/src/commands/command_cache.c index 124fcd761..22cb8baaa 100644 --- a/ctrl/libhicnctrl/src/commands/command_cache.c +++ b/ctrl/libhicnctrl/src/commands/command_cache.c @@ -1,3 +1,23 @@ +/* + * Copyright (c) 2021-2023 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 command_cache.h + * \brief Implementation of cache command. + */ + #include #include diff --git a/ctrl/libhicnctrl/src/commands/command_connection.c b/ctrl/libhicnctrl/src/commands/command_connection.c index 1659a9860..a43934fdf 100644 --- a/ctrl/libhicnctrl/src/commands/command_connection.c +++ b/ctrl/libhicnctrl/src/commands/command_connection.c @@ -1,3 +1,22 @@ +/* + * Copyright (c) 2021-2023 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 command_connection.h + * \brief Implementation of connection command. + */ #include #include diff --git a/ctrl/libhicnctrl/src/commands/command_face.c b/ctrl/libhicnctrl/src/commands/command_face.c index f60bef18d..e383de1b5 100644 --- a/ctrl/libhicnctrl/src/commands/command_face.c +++ b/ctrl/libhicnctrl/src/commands/command_face.c @@ -1,3 +1,22 @@ +/* + * Copyright (c) 2021-2023 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 command_face.h + * \brief Implementation of face command. + */ #include /* Parameters */ diff --git a/ctrl/libhicnctrl/src/commands/command_listener.c b/ctrl/libhicnctrl/src/commands/command_listener.c index cfcd22f48..604c0a672 100644 --- a/ctrl/libhicnctrl/src/commands/command_listener.c +++ b/ctrl/libhicnctrl/src/commands/command_listener.c @@ -1,3 +1,22 @@ +/* + * Copyright (c) 2021-2023 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 command_listener.h + * \brief Implementation of listener command. + */ #include #include diff --git a/ctrl/libhicnctrl/src/commands/command_mapme.c b/ctrl/libhicnctrl/src/commands/command_mapme.c index c67b7704f..7dcca038c 100644 --- a/ctrl/libhicnctrl/src/commands/command_mapme.c +++ b/ctrl/libhicnctrl/src/commands/command_mapme.c @@ -1,3 +1,22 @@ +/* + * Copyright (c) 2021-2023 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 command_mapme.h + * \brief Implementation of mapme command. + */ #include #include diff --git a/ctrl/libhicnctrl/src/commands/command_policy.c b/ctrl/libhicnctrl/src/commands/command_policy.c index 2fc7a0a42..eaf949880 100644 --- a/ctrl/libhicnctrl/src/commands/command_policy.c +++ b/ctrl/libhicnctrl/src/commands/command_policy.c @@ -1,3 +1,23 @@ +/* + * Copyright (c) 2021-2023 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 command_policy.h + * \brief Implementation of policy command. + */ + #if 0 #include diff --git a/ctrl/libhicnctrl/src/commands/command_punting.c b/ctrl/libhicnctrl/src/commands/command_punting.c index b845c52ee..a274583b1 100644 --- a/ctrl/libhicnctrl/src/commands/command_punting.c +++ b/ctrl/libhicnctrl/src/commands/command_punting.c @@ -1,3 +1,23 @@ +/* + * Copyright (c) 2021-2023 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 command_punting.h + * \brief Implementation of punting command. + */ + #if 0 #include diff --git a/ctrl/libhicnctrl/src/commands/command_route.c b/ctrl/libhicnctrl/src/commands/command_route.c index 5db710111..95d0a3a43 100644 --- a/ctrl/libhicnctrl/src/commands/command_route.c +++ b/ctrl/libhicnctrl/src/commands/command_route.c @@ -1,3 +1,23 @@ +/* + * Copyright (c) 2021-2023 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 command_route.c + * \brief Implementation of route command. + */ + #include #include #include "../objects/route.h" @@ -22,7 +42,7 @@ .offset3 = offsetof(hc_route_t, family), \ } -#define cost \ +#define p_cost \ { \ .name = "cost", .help = "Positive integer representing cost.", \ .type = TYPE_INT(1, 255), .offset = offsetof(hc_route_t, cost), \ @@ -73,19 +93,41 @@ } /* Commands */ -int on_route_create(hc_route_t* route) { + +int on_route_parsed(hc_route_t* route) { if (hc_route_has_face(route)) { route->face.admin_state = FACE_STATE_UP; route->face.id = INVALID_FACE_ID; } + route->face_id = INVALID_FACE_ID; // we populate face name + if (route->cost == 0) route->cost = 1; return 0; } +static const command_parser_t command_route_create1 = { + .action = ACTION_CREATE, + .object_type = OBJECT_TYPE_ROUTE, + .nparams = 1, + .parameters = {prefix}, + .post_hook = (parser_hook_t)on_route_parsed, +}; +COMMAND_REGISTER(command_route_create1); + +static const command_parser_t command_route_create2 = { + .action = ACTION_CREATE, + .object_type = OBJECT_TYPE_ROUTE, + .nparams = 2, + .parameters = {symbolic_or_id, prefix}, + .post_hook = (parser_hook_t)on_route_parsed, +}; +COMMAND_REGISTER(command_route_create2); + static const command_parser_t command_route_create3 = { .action = ACTION_CREATE, .object_type = OBJECT_TYPE_ROUTE, .nparams = 3, - .parameters = {symbolic_or_id, prefix, cost}, + .parameters = {symbolic_or_id, prefix, p_cost}, + .post_hook = (parser_hook_t)on_route_parsed, }; COMMAND_REGISTER(command_route_create3); @@ -93,8 +135,8 @@ static const command_parser_t command_route_create5 = { .action = ACTION_CREATE, .object_type = OBJECT_TYPE_ROUTE, .nparams = 5, - .parameters = {prefix, cost, type_tcp_udp, remote_address, remote_port}, - .post_hook = (parser_hook_t)on_route_create, + .parameters = {prefix, p_cost, type_tcp_udp, remote_address, remote_port}, + .post_hook = (parser_hook_t)on_route_parsed, }; COMMAND_REGISTER(command_route_create5); @@ -102,9 +144,9 @@ static const command_parser_t command_route_create6 = { .action = ACTION_CREATE, .object_type = OBJECT_TYPE_ROUTE, .nparams = 6, - .parameters = {prefix, cost, type_tcp_udp, remote_address, remote_port, + .parameters = {prefix, p_cost, type_tcp_udp, remote_address, remote_port, interface}, - .post_hook = (parser_hook_t)on_route_create, + .post_hook = (parser_hook_t)on_route_parsed, }; COMMAND_REGISTER(command_route_create6); @@ -112,9 +154,9 @@ static const command_parser_t command_route_create7 = { .action = ACTION_CREATE, .object_type = OBJECT_TYPE_ROUTE, .nparams = 7, - .parameters = {prefix, cost, type_tcp_udp, local_address, local_port, + .parameters = {prefix, p_cost, type_tcp_udp, local_address, local_port, remote_address, remote_port}, - .post_hook = (parser_hook_t)on_route_create, + .post_hook = (parser_hook_t)on_route_parsed, }; COMMAND_REGISTER(command_route_create7); @@ -122,9 +164,9 @@ static const command_parser_t command_route_create8 = { .action = ACTION_CREATE, .object_type = OBJECT_TYPE_ROUTE, .nparams = 8, - .parameters = {prefix, cost, type_tcp_udp, local_address, local_port, + .parameters = {prefix, p_cost, type_tcp_udp, local_address, local_port, remote_address, remote_port, interface}, - .post_hook = (parser_hook_t)on_route_create, + .post_hook = (parser_hook_t)on_route_parsed, }; COMMAND_REGISTER(command_route_create8); @@ -140,5 +182,6 @@ static const command_parser_t command_route_remove = { .object_type = OBJECT_TYPE_ROUTE, .nparams = 2, .parameters = {symbolic_or_id, prefix}, + .post_hook = (parser_hook_t)on_route_parsed, }; COMMAND_REGISTER(command_route_remove); diff --git a/ctrl/libhicnctrl/src/commands/command_stats.c b/ctrl/libhicnctrl/src/commands/command_stats.c index f02a68069..d69f22a19 100644 --- a/ctrl/libhicnctrl/src/commands/command_stats.c +++ b/ctrl/libhicnctrl/src/commands/command_stats.c @@ -1,3 +1,22 @@ +/* + * Copyright (c) 2021-2023 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 command_stats.h + * \brief Implementation of stats command. + */ #include #include diff --git a/ctrl/libhicnctrl/src/commands/command_strategy.c b/ctrl/libhicnctrl/src/commands/command_strategy.c index f7f5974d1..2aac924c4 100644 --- a/ctrl/libhicnctrl/src/commands/command_strategy.c +++ b/ctrl/libhicnctrl/src/commands/command_strategy.c @@ -1,3 +1,22 @@ +/* + * Copyright (c) 2021-2023 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 command_strategy.h + * \brief Implementation of strategy command. + */ #include /* Parameters */ diff --git a/ctrl/libhicnctrl/src/commands/command_subscription.c b/ctrl/libhicnctrl/src/commands/command_subscription.c index 886ee454a..ee2455b1c 100644 --- a/ctrl/libhicnctrl/src/commands/command_subscription.c +++ b/ctrl/libhicnctrl/src/commands/command_subscription.c @@ -1,3 +1,22 @@ +/* + * Copyright (c) 2021-2023 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 command_subscription.h + * \brief Implementation of subscription command. + */ #include #include diff --git a/ctrl/libhicnctrl/src/hicnctrl.c b/ctrl/libhicnctrl/src/hicnctrl.c index fd028f64a..478997ec1 100644 --- a/ctrl/libhicnctrl/src/hicnctrl.c +++ b/ctrl/libhicnctrl/src/hicnctrl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Copyright (c) 2021-2023 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: @@ -14,7 +14,7 @@ */ /** - * \file cli.c + * \file hicnctrl.c * \brief Command line interface */ #include // isalpha isalnum @@ -122,7 +122,7 @@ void usage_forwarding_strategy(const char *prog, bool header, bool verbose) { void usage_listener_create(const char *prog, bool header, bool verbose) { if (header) usage_header(); - fprintf(stderr, "%s -l NAME TYPE LOCAL_ADDRESS LOCAL_PORT [INTERFACE_NAME]\n", + fprintf(stderr, "%s -l TYPE NAME LOCAL_ADDRESS LOCAL_PORT [INTERFACE_NAME]\n", prog); if (verbose) fprintf(stderr, " Create a listener on specified address and port.\n"); @@ -323,7 +323,8 @@ USAGE: int main(int argc, char *argv[]) { int rc = 1; - hc_command_t command = {0}; + hc_command_t command; + memset(&command, 0, sizeof(command)); char buf[MAXSZ_HC_OBJECT]; log_conf.log_level = LOG_INFO; diff --git a/ctrl/libhicnctrl/src/module.h b/ctrl/libhicnctrl/src/module.h index c06f3ce86..51fd9f942 100644 --- a/ctrl/libhicnctrl/src/module.h +++ b/ctrl/libhicnctrl/src/module.h @@ -1,3 +1,23 @@ +/* + * Copyright (c) 2021-2023 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 modules.h + * \brief hicn-light module interface. + */ + #ifndef HICNCTRL_MODULE_H #define HICNCTRL_MODULE_H @@ -31,11 +51,13 @@ typedef struct { [ACTION_CREATE] = NULL, \ [ACTION_DELETE] = NULL, \ [ACTION_LIST] = NULL, \ + [ACTION_SET] = NULL, \ }, \ .serialize = { \ [ACTION_CREATE] = NULL, \ [ACTION_DELETE] = NULL, \ [ACTION_LIST] = NULL, \ + [ACTION_SET] = NULL, \ }, \ } diff --git a/ctrl/libhicnctrl/src/module_object_vft.h b/ctrl/libhicnctrl/src/module_object_vft.h deleted file mode 100644 index 2651b50a3..000000000 --- a/ctrl/libhicnctrl/src/module_object_vft.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef HICNCTRL_MODULES_OBJECT_MODULE_VFT_H -#define HICNCTRL_MODULES_OBJECT_MODULE_VFT_H - -#endif /* HICNCTRL_MODULES_OBJECT_MODULE_VFT_H */ diff --git a/ctrl/libhicnctrl/src/modules/CMakeLists.txt b/ctrl/libhicnctrl/src/modules/CMakeLists.txt index f7bd2f83a..f3e1a6342 100644 --- a/ctrl/libhicnctrl/src/modules/CMakeLists.txt +++ b/ctrl/libhicnctrl/src/modules/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2021-2022 Cisco and/or its affiliates. +# Copyright (c) 2021-2023 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: @@ -19,6 +19,7 @@ list(APPEND HICNLIGHT_MODULE_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/hicn_light/connection.c ${CMAKE_CURRENT_SOURCE_DIR}/hicn_light/face.c ${CMAKE_CURRENT_SOURCE_DIR}/hicn_light/listener.c + ${CMAKE_CURRENT_SOURCE_DIR}/hicn_light/mapme.c ${CMAKE_CURRENT_SOURCE_DIR}/hicn_light/route.c ${CMAKE_CURRENT_SOURCE_DIR}/hicn_light/stats.c ${CMAKE_CURRENT_SOURCE_DIR}/hicn_light/strategy.c @@ -30,6 +31,7 @@ list(APPEND HICNLIGHT_MODULE_HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/hicn_light/connection.h ${CMAKE_CURRENT_SOURCE_DIR}/hicn_light/face.h ${CMAKE_CURRENT_SOURCE_DIR}/hicn_light/listener.h + ${CMAKE_CURRENT_SOURCE_DIR}/hicn_light/mapme.h ${CMAKE_CURRENT_SOURCE_DIR}/hicn_light/route.h ${CMAKE_CURRENT_SOURCE_DIR}/hicn_light/stats.h ${CMAKE_CURRENT_SOURCE_DIR}/hicn_light/strategy.h diff --git a/ctrl/libhicnctrl/src/modules/hicn_light.c b/ctrl/libhicnctrl/src/modules/hicn_light.c index a2577c31b..96cdda2d2 100644 --- a/ctrl/libhicnctrl/src/modules/hicn_light.c +++ b/ctrl/libhicnctrl/src/modules/hicn_light.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Copyright (c) 2021-2023 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,8 +48,9 @@ #include "hicn_light/base.h" #include "hicn_light/connection.h" -#include "hicn_light/listener.h" #include "hicn_light/face.h" +#include "hicn_light/listener.h" +#include "hicn_light/mapme.h" #include "hicn_light/route.h" #include "hicn_light/stats.h" #include "hicn_light/strategy.h" @@ -200,8 +201,13 @@ static int hicnlight_process_header(hc_sock_t *sock) { } if (!request) { ERROR("[hc_sock_light_process] No request matching sequence number"); + /* + * Currently: Ignore packet (alternatively: return 0 to discard in case of + * error; move s->got_header later in this case) + */ return -1; } + sock->current_request = request; hc_request_t *current_request = hc_request_get_current(request); hc_data_t *data = hc_request_get_data(current_request); @@ -1412,7 +1418,7 @@ int hc_sock_initialize_module(hc_sock_t *s) { hc_sock_light.object_vft[OBJECT_TYPE_FACE] = HC_MODULE_OBJECT_OPS_EMPTY; hc_sock_light.object_vft[OBJECT_TYPE_PUNTING] = HC_MODULE_OBJECT_OPS_EMPTY; hc_sock_light.object_vft[OBJECT_TYPE_CACHE] = HC_MODULE_OBJECT_OPS_EMPTY; - hc_sock_light.object_vft[OBJECT_TYPE_MAPME] = HC_MODULE_OBJECT_OPS_EMPTY; + hc_sock_light.object_vft[OBJECT_TYPE_MAPME] = hicnlight_mapme_module_ops; hc_sock_light.object_vft[OBJECT_TYPE_WLDR] = HC_MODULE_OBJECT_OPS_EMPTY; hc_sock_light.object_vft[OBJECT_TYPE_POLICY] = HC_MODULE_OBJECT_OPS_EMPTY; hc_sock_light.object_vft[OBJECT_TYPE_ROUTE] = hicnlight_route_module_ops; diff --git a/ctrl/libhicnctrl/src/modules/hicn_light/mapme.c b/ctrl/libhicnctrl/src/modules/hicn_light/mapme.c index de75d82a8..04eb36e24 100644 --- a/ctrl/libhicnctrl/src/modules/hicn_light/mapme.c +++ b/ctrl/libhicnctrl/src/modules/hicn_light/mapme.c @@ -1,139 +1,68 @@ +/* + * Copyright (c) 2021-2023 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 modules/hicn_light/mapme.c + * \brief Implementation of mapme object VFT for hicn_light. + */ + +#include #include "mapme.h" -static int _hcng_mapme_set(hc_sock_t *socket, int enabled) { -#if 0 - msg_mapme_enable_t msg = {.header = - { - .message_type = REQUEST_LIGHT, - .command_id = COMMAND_TYPE_MAPME_ENABLE, - .length = 1, - .seq_num = 0, - }, - .payload = { - .activate = enabled, - }}; - - hc_command_params_t params = { - .cmd = ACTION_SET, - .cmd_id = COMMAND_TYPE_MAPME_ENABLE, - .size_in = sizeof(cmd_mapme_enable_t), - .size_out = 0, - .parse = NULL, - }; - - return _hcng_execute_command(socket, (hc_msg_t *)&msg, sizeof(msg), ¶ms, - NULL, false); -#endif - return 0; // XXX added +static int hicnlight_mapme_parse(const uint8_t *buffer, size_t size, + hc_mapme_t *mapme) { + return -1; } -static int _hcng_mapme_set_discovery(hc_sock_t *socket, int enabled) { -#if 0 - msg_mapme_enable_t msg = { - .header = - { - .message_type = REQUEST_LIGHT, - .command_id = COMMAND_TYPE_MAPME_SET_DISCOVERY, - .length = 1, - .seq_num = 0, - }, - .payload = { - .activate = enabled, - }}; - - hc_command_params_t params = { - .cmd = ACTION_SET, - .cmd_id = COMMAND_TYPE_MAPME_SET_DISCOVERY, - .size_in = sizeof(cmd_mapme_set_discovery_t), - .size_out = 0, - .parse = NULL, - }; - - return _hcng_execute_command(socket, (hc_msg_t *)&msg, sizeof(msg), ¶ms, - NULL, false); -#endif - return 0; // XXX added +int _hicnlight_mapme_parse(const uint8_t *buffer, size_t size, + hc_object_t *object) { + return hicnlight_mapme_parse(buffer, size, &object->mapme); } -static int _hcng_mapme_set_timescale(hc_sock_t *socket, uint32_t timescale) { -#if 0 - msg_mapme_set_timescale_t msg = { - .header = - { - .message_type = REQUEST_LIGHT, - .command_id = COMMAND_TYPE_MAPME_SET_TIMESCALE, - .length = 1, - .seq_num = 0, - }, - .payload = { - .timePeriod = timescale, - }}; - - hc_command_params_t params = { - .cmd = ACTION_SET, - .cmd_id = COMMAND_TYPE_MAPME_SET_TIMESCALE, - .size_in = sizeof(cmd_mapme_set_timescale_t), - .size_out = 0, - .parse = NULL, - }; - - return _hcng_execute_command(socket, (hc_msg_t *)&msg, sizeof(msg), ¶ms, - NULL, false); -#endif - return 0; // XXX added +int hicnlight_mapme_serialize_create(const hc_object_t *object, + uint8_t *packet) { + const hc_mapme_t *mapme = &object->mapme; + + msg_mapme_add_t *msg = (msg_mapme_add_t *)packet; + *msg = (msg_mapme_add_t){.header = + { + .message_type = REQUEST_LIGHT, + .command_id = COMMAND_TYPE_MAPME_ADD, + .length = 1, + .seq_num = 0, + }, + + .payload = {.face_id = mapme->face_id, + .family = mapme->family, + .address = mapme->address, + .len = mapme->len}}; + + return sizeof(msg_mapme_add_t); } -static int _hcng_mapme_set_retx(hc_sock_t *socket, uint32_t timescale) { -#if 0 - msg_mapme_set_retx_t msg = {.header = - { - .message_type = REQUEST_LIGHT, - .command_id = COMMAND_TYPE_MAPME_SET_RETX, - .length = 1, - .seq_num = 0, - }, - .payload = { - .timePeriod = timescale, - }}; - - hc_command_params_t params = { - .cmd = ACTION_SET, - .cmd_id = COMMAND_TYPE_MAPME_SET_RETX, - .size_in = sizeof(msg_mapme_set_retx_t), - .size_out = 0, - .parse = NULL, - }; - - return _hcng_execute_command(socket, (hc_msg_t *)&msg, sizeof(msg), ¶ms, - NULL, false); -#endif - return 0; // XXX added +int hicnlight_mapme_serialize_delete(const hc_object_t *object, + uint8_t *packet) { + return -1; } -static int _hcng_mapme_send_update(hc_sock_t *socket, hc_mapme_t *mapme) { -#if 0 - if (!IS_VALID_FAMILY(mapme->family)) return -1; - - msg_mapme_send_update_t msg = { - .header = - { - .message_type = REQUEST_LIGHT, - .command_id = COMMAND_TYPE_MAPME_SEND_UPDATE, - .length = 1, - .seq_num = 0, - }, - }; - - hc_command_params_t params = { - .cmd = ACTION_UPDATE, - .cmd_id = COMMAND_TYPE_MAPME_SEND_UPDATE, - .size_in = sizeof(msg_mapme_send_update_t), - .size_out = 0, - .parse = NULL, - }; +int hicnlight_mapme_serialize_list(const hc_object_t *object, uint8_t *packet) { + return -1; +} - return _hcng_execute_command(socket, (hc_msg_t *)&msg, sizeof(msg), ¶ms, - NULL, false); -#endif - return 0; // XXX added +int hicnlight_mapme_serialize_set(const hc_object_t *object, uint8_t *packet) { + return -1; } + +DECLARE_MODULE_OBJECT_OPS(hicnlight, mapme); diff --git a/ctrl/libhicnctrl/src/modules/hicn_light/mapme.h b/ctrl/libhicnctrl/src/modules/hicn_light/mapme.h new file mode 100644 index 000000000..58a943b67 --- /dev/null +++ b/ctrl/libhicnctrl/src/modules/hicn_light/mapme.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023 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 modules/hicn_light/mapme.h + * \brief mapme object VFT for hicn_light. + */ + +#ifndef HICNCTRL_MODULE_HICNLIGHT_MAPME_H +#define HICNCTRL_MODULE_HICNLIGHT_MAPME_H + +#include "../../module.h" + +DECLARE_MODULE_OBJECT_OPS_H(hicnlight, mapme); + +#endif /* HICNCTRL_MODULE_HICNLIGHT_MAPME_H */ diff --git a/ctrl/libhicnctrl/src/object_private.h b/ctrl/libhicnctrl/src/object_private.h index 2be12fd5e..1aea86639 100644 --- a/ctrl/libhicnctrl/src/object_private.h +++ b/ctrl/libhicnctrl/src/object_private.h @@ -1,11 +1,33 @@ +/* + * Copyright (c) 2021-2023 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 object_private.h + * \brief Helper functions for object management. + */ + #ifndef HICNCTRL_OBJECT_PRIVATE_H #define HICNCTRL_OBJECT_PRIVATE_H +#include + #define INT_CMP(x, y) ((x > y) ? 1 : (x < y) ? -1 : 0) // XXX Those are always true #define IS_VALID_ADDRESS(x) (1) -#define IS_VALID_CONNECTION_ID(x) (1) // XXX ID +#define IS_VALID_CONNECTION_ID(x) (x != INVALID_FACE_ID) #define IS_VALID_ROUTE_COST(x) (1) #define IS_VALID_PREFIX_LEN(x) (1) #define IS_VALID_POLICY(x) (1) diff --git a/ctrl/libhicnctrl/src/object_vft.c b/ctrl/libhicnctrl/src/object_vft.c index 01d2dab88..4dc59c378 100644 --- a/ctrl/libhicnctrl/src/object_vft.c +++ b/ctrl/libhicnctrl/src/object_vft.c @@ -1,22 +1,44 @@ +/* + * Copyright (c) 2021-2023 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 object_vft.c + * \brief Implementation of object VFT. + */ + #include "object_vft.h" #include "objects/listener.h" #include "objects/connection.h" #include "objects/route.h" #include "objects/face.h" +#include "objects/mapme.h" #include "objects/stats.h" #include "objects/strategy.h" #include "objects/subscription.h" #include "objects/active_interface.h" const hc_object_ops_t *object_vft[] = { - [OBJECT_TYPE_LISTENER] = &hc_listener_ops, [OBJECT_TYPE_CONNECTION] = &hc_connection_ops, + [OBJECT_TYPE_LISTENER] = &hc_listener_ops, [OBJECT_TYPE_ROUTE] = &hc_route_ops, [OBJECT_TYPE_FACE] = &hc_face_ops, - [OBJECT_TYPE_FACE_STATS] = &hc_face_stats_ops, - [OBJECT_TYPE_STATS] = &hc_stats_ops, [OBJECT_TYPE_STRATEGY] = &hc_strategy_ops, + [OBJECT_TYPE_MAPME] = &hc_mapme_ops, [OBJECT_TYPE_SUBSCRIPTION] = &hc_subscription_ops, [OBJECT_TYPE_ACTIVE_INTERFACE] = &hc_active_interface_ops, + [OBJECT_TYPE_STATS] = &hc_stats_ops, + [OBJECT_TYPE_FACE_STATS] = &hc_face_stats_ops, }; diff --git a/ctrl/libhicnctrl/src/objects/mapme.c b/ctrl/libhicnctrl/src/objects/mapme.c new file mode 100644 index 000000000..1acdcb35a --- /dev/null +++ b/ctrl/libhicnctrl/src/objects/mapme.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2021-2023 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 mapme.c + * \brief Implementation of mapme object. + */ + +#include +#include +#include +#include + +#include "../object_private.h" +#include "../object_vft.h" +#include "face.h" +#include "base.h" + +/* MAPME VALIDATE */ + +int hc_mapme_validate(const hc_mapme_t *mapme, bool allow_partial) { + int has_family = 0; + int has_address = 0; + int has_len = 0; + + if (allow_partial) return 0; + + if (mapme->family != AF_UNSPEC) { + if (!IS_VALID_FAMILY(mapme->family)) { + ERROR("[hc_mapme_validate] Invalid family specified"); + return -1; + } + has_family = 1; + } + + if (!hicn_ip_address_empty(&mapme->address)) { + if (!IS_VALID_ADDRESS(mapme->address)) { + ERROR("[hc_mapme_validate] Invalid remote_addr specified"); + return -1; + } + has_address = 1; + } + + if (!IS_VALID_PREFIX_LEN(mapme->len)) { + ERROR("[hc_mapme_validate] Invalid len"); + return -1; + } + has_len = 1; + return has_family && has_address && has_len; +} + +int _hc_mapme_validate(const hc_object_t *object, bool allow_partial) { + return hc_mapme_validate(&object->mapme, allow_partial); +} + +/* MAPME CMP */ + +int hc_mapme_cmp(const hc_mapme_t *mapme1, const hc_mapme_t *mapme2) { + return -1; +} + +int _hc_mapme_cmp(const hc_object_t *object1, const hc_object_t *object2) { + return -1; +} + +/* MAPME SNPRINTF */ + +int hc_mapme_snprintf(char *s, size_t size, const hc_mapme_t *mapme) { + return -1; +} + +int _hc_mapme_snprintf(char *s, size_t size, const hc_object_t *object) { + return -1; +} + +int hc_mapme_create(hc_sock_t *s, hc_mapme_t *mapme) { + hc_object_t object; + memset(&object, 0, sizeof(hc_object_t)); + object.mapme = *mapme; + return hc_execute(s, ACTION_CREATE, OBJECT_TYPE_MAPME, &object, NULL); +} + +DECLARE_OBJECT_OPS(OBJECT_TYPE_MAPME, mapme); diff --git a/ctrl/libhicnctrl/src/objects/mapme.h b/ctrl/libhicnctrl/src/objects/mapme.h new file mode 100644 index 000000000..488f97cd5 --- /dev/null +++ b/ctrl/libhicnctrl/src/objects/mapme.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021-2023 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 mapme.h + * \brief Route. + */ + +#ifndef HICNCTRL_IMPL_OBJECTS_MAPME_H +#define HICNCTRL_IMPL_OBJECTS_MAPME_H + +#include "../object_vft.h" + +bool hc_mapme_has_face(const hc_mapme_t* mapme); + +DECLARE_OBJECT_OPS_H(OBJECT_TYPE_MAPME, mapme); + +#endif /* HICNCTRL_IMPL_OBJECTS_MAPME_H */ diff --git a/ctrl/libhicnctrl/src/objects/route.c b/ctrl/libhicnctrl/src/objects/route.c index f2d0636a7..4bdaa0afb 100644 --- a/ctrl/libhicnctrl/src/objects/route.c +++ b/ctrl/libhicnctrl/src/objects/route.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Copyright (c) 2021-2023 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: @@ -42,11 +42,9 @@ int hc_route_validate(const hc_route_t *route, bool allow_partial) { int has_family = 0; int has_remote_addr = 0; - if (!IS_VALID_CONNECTION_ID(route->face_id)) { - ERROR("[hc_route_validate] Invalid face id"); - return -1; + if (IS_VALID_CONNECTION_ID(route->face_id)) { + has_id = 1; } - has_id = 1; if (!isempty(route->face_name)) { if (!IS_VALID_NAME(route->face_name)) { @@ -64,6 +62,8 @@ int hc_route_validate(const hc_route_t *route, bool allow_partial) { has_family = 1; } + //::/0 is a valid remote addr +#if 0 if (!hicn_ip_address_empty(&route->remote_addr)) { if (!IS_VALID_ADDRESS(route->remote_addr)) { ERROR("[hc_route_validate] Invalid remote_addr specified"); @@ -71,16 +71,21 @@ int hc_route_validate(const hc_route_t *route, bool allow_partial) { } has_remote_addr = 1; } +#else + has_remote_addr = 1; +#endif if (!IS_VALID_ROUTE_COST(route->cost)) { ERROR("[hc_route_validate] Invalid cost"); return -1; } +#if 0 if (!IS_VALID_PREFIX_LEN(route->len)) { ERROR("[hc_route_validate] Invalid len"); return -1; } +#endif if (hc_route_has_face(route)) { if (hc_face_validate(&route->face, allow_partial) < 0) { @@ -90,12 +95,10 @@ int hc_route_validate(const hc_route_t *route, bool allow_partial) { has_face = 1; } - int has_face_info = has_id || has_name || has_face; - - if (!has_face_info) return -1; - if (allow_partial && (has_name + has_face != 1)) return -1; - - if (has_face_info && has_family && has_remote_addr) return 0; + /* We also allow routes without faces, hence the '>' sign */ + if (allow_partial && (has_id + has_name + has_face > 1)) return -1; + // if (has_face_info && has_family && has_remote_addr) return 0; + if (has_family && has_remote_addr) return 0; return -1; } diff --git a/hicn-light/src/hicn/config/CMakeLists.txt b/hicn-light/src/hicn/config/CMakeLists.txt index 36abe96ce..8e9415f7d 100644 --- a/hicn-light/src/hicn/config/CMakeLists.txt +++ b/hicn-light/src/hicn/config/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2021-2022 Cisco and/or its affiliates. +# Copyright (c) 2021-2023 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,6 +22,7 @@ list(APPEND SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/../../../../ctrl/libhicnctrl/src/modules/hicn_light/connection.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../ctrl/libhicnctrl/src/modules/hicn_light/listener.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../ctrl/libhicnctrl/src/modules/hicn_light/face.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../ctrl/libhicnctrl/src/modules/hicn_light/mapme.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../ctrl/libhicnctrl/src/modules/hicn_light/route.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../ctrl/libhicnctrl/src/modules/hicn_light/stats.c ${CMAKE_CURRENT_SOURCE_DIR}/../../../../ctrl/libhicnctrl/src/modules/hicn_light/strategy.c diff --git a/hicn-light/src/hicn/config/commands.c b/hicn-light/src/hicn/config/commands.c index c6212aaf4..47ea23a8a 100644 --- a/hicn-light/src/hicn/config/commands.c +++ b/hicn-light/src/hicn/config/commands.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Copyright (c) 2021-2023 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: @@ -351,6 +351,7 @@ uint8_t *configuration_on_listener_list(forwarder_t *forwarder, uint8_t *packet, size_t n = listener_table_len(table); msg_listener_list_t *msg_received = (msg_listener_list_t *)packet; uint8_t command_id = msg_received->header.command_id; + INFO("listener list seq num %d", msg_received->header.seq_num); uint32_t seq_num = msg_received->header.seq_num; msg_listener_list_reply_t *msg = NULL; @@ -733,7 +734,11 @@ uint8_t *configuration_on_route_add(forwarder_t *forwarder, uint8_t *packet, unsigned conn_id = symbolic_to_conn_id_self( forwarder, control->symbolic_or_connid, ingress_id); + + /* We accept routes without conn_id */ +#if 0 if (!connection_id_is_valid(conn_id)) goto NACK; +#endif hicn_ip_prefix_t prefix = {.family = control->family, .address = control->address, @@ -1165,7 +1170,7 @@ uint8_t *configuration_on_punting_add(forwarder_t *forwarder, uint8_t *packet, #if !defined(__APPLE__) && !defined(_WIN32) && defined(PUNTING) cmd_punting_add_t *control = &msg->payload; - if (ip_address_empty(&control->address)) goto NACK; + if (hicn_ip_address_empty(&control->address)) goto NACK; /* This is for hICN listeners only */ // XXX add check ! @@ -1316,15 +1321,18 @@ NACK: return (uint8_t *)msg; } -uint8_t *configuration_on_mapme_send_update(forwarder_t *forwarder, - uint8_t *packet, - unsigned ingress_id, - size_t *reply_size) { +uint8_t *configuration_on_mapme_add(forwarder_t *forwarder, uint8_t *packet, + unsigned ingress_id, size_t *reply_size) { assert(forwarder); assert(packet); - INFO("CMD: mapme send update (ingress=%d)", ingress_id); - msg_mapme_send_update_t *msg = (msg_mapme_send_update_t *)packet; + /* Check ingress is local (for now this is only used locally) */ + connection_table_t *table = forwarder_get_connection_table(forwarder); + const connection_t *connection = connection_table_at(table, ingress_id); + + msg_mapme_add_t *msg = (msg_mapme_add_t *)packet; + + if (!connection_is_local(connection)) goto NACK; *reply_size = sizeof(msg_header_t); @@ -1333,20 +1341,69 @@ uint8_t *configuration_on_mapme_send_update(forwarder_t *forwarder, mapme_t *mapme = forwarder_get_mapme(forwarder); - /* - * The command triggers a mapme update for all prefixes produced on this - * face - * */ - fib_foreach_entry(fib, entry, { - const nexthops_t *nexthops = fib_entry_get_nexthops(entry); - nexthops_foreach(nexthops, nexthop, { - if (nexthop != ingress_id) continue; - /* This entry points to the producer face */ - mapme_set_all_adjacencies(mapme, entry); - break; + cmd_mapme_add_t *control = &msg->payload; + /* If the message comes from the producer, address, family, len and + * face_id will be NULL + */ + if (hicn_ip_address_empty(&control->address) && (control->len == 0) && + (control->family == 0) && (control->face_id == 0)) { + /* + * The command triggers a mapme update for all prefixes produced on this + * face + * + * XXX This should in fact be an UPDATE command + */ + + fib_foreach_entry(fib, entry, { + const nexthops_t *nexthops = fib_entry_get_nexthops(entry); + nexthops_foreach(nexthops, nexthop, { + if (nexthop != ingress_id) continue; + /* This entry points to the producer face */ + mapme_set_all_adjacencies(mapme, entry); + break; + }); }); - }); + goto END; + } + + /* Control plane triggered + * + * We might not only receive MAP-Me update requests for prefixes we own, + * but also for more specific ones (for instance, we have a /64 and + * want to send an update on a /128). This requires a FIB lookup. + * + * NOTE: we need to avoid modifying the FIB because of this. + * + * TODO: + * - assert face_id is valid and exists + * - assert family is correct + */ + + hicn_prefix_t name_prefix = HICN_PREFIX_EMPTY; + hicn_prefix_create_from_ip_address_len(&control->address, control->len, + &name_prefix); + +#ifdef HICN_MAPME_ALLOW_NONEXISTING_FIB_ENTRY + fib_entry_t *entry = fib_contains(fib, &name_prefix); + if (!entry) { + entry = mapme_create_fib_entry(mapme, &name_prefix, INVALID_FACE_ID); + if (!entry) goto NACK; // we could also perform as in the other branch + } + mapme_set_adjacency(mapme, entry, control->face_id, NULL); + +#else + fib_entry_t *entry = fib_match_prefix(fib, &name_prefix); + + const hicn_prefix_t *prefix = fib_entry_get_prefix(entry); + if (hicn_prefix_get_len(prefix) == control->len) { + mapme_set_adjacency(mapme, entry, control->face_id, NULL); + } else { + mapme_set_adjacency(mapme, NULL, control->face_id, prefix); + } +#endif + +END: make_ack(msg); return (uint8_t *)msg; diff --git a/hicn-light/src/hicn/core/connection.h b/hicn-light/src/hicn/core/connection.h index b459a6d81..e177e2039 100644 --- a/hicn-light/src/hicn/core/connection.h +++ b/hicn-light/src/hicn/core/connection.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Cisco and/or its affiliates. + * Copyright (c) 2021-2023 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: @@ -31,7 +31,7 @@ #include #endif /* WITH_POLICY */ -#define CONNECTION_ID_UNDEFINED ~0 +#define CONNECTION_ID_UNDEFINED INVALID_FACE_ID #define foreach_connection_event \ _(UNDEFINED) \ diff --git a/hicn-light/src/hicn/core/fib.c b/hicn-light/src/hicn/core/fib.c index 5f8788155..c44d2daf0 100644 --- a/hicn-light/src/hicn/core/fib.c +++ b/hicn-light/src/hicn/core/fib.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Copyright (c) 2021-2023 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: @@ -291,7 +291,7 @@ void _fib_remove(fib_t *fib, fib_node_t *curr, fib_node_t *parent) { * / \ * l L */ -void fib_add(fib_t *fib, fib_entry_t *entry) { +fib_entry_t *fib_add(fib_t *fib, fib_entry_t *entry) { assert(fib); assert(entry); @@ -329,17 +329,12 @@ void fib_add(fib_t *fib, fib_entry_t *entry) { /* Case 2 */ if (search.prefix_len == search.match_len && prefix_len == search.match_len) { - if (!curr->is_used) { - curr->is_used = true; - if (curr->entry) fib_entry_free(curr->entry); - curr->entry = entry; - fib->size++; - } else { - const nexthops_t *nexthops = fib_entry_get_nexthops(entry); - nexthops_foreach(nexthops, nexthop, - { fib_entry_nexthops_add(curr->entry, nexthop); }); - fib_entry_free(entry); - } + const nexthops_t *nexthops = fib_entry_get_nexthops(entry); + nexthops_foreach(nexthops, nexthop, + { fib_entry_nexthops_add(curr->entry, nexthop); }); + fib_entry_free(entry); + entry = curr->entry; + curr->is_used = true; goto END; } @@ -366,7 +361,7 @@ END: #if 0 fib_dump(fib); #endif - ; /* required by clang */ + return entry; } /* diff --git a/hicn-light/src/hicn/core/fib.h b/hicn-light/src/hicn/core/fib.h index 501935b0b..4fb5009f5 100644 --- a/hicn-light/src/hicn/core/fib.h +++ b/hicn-light/src/hicn/core/fib.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Copyright (c) 2021-2023 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,7 +30,7 @@ void fib_free(fib_t *fib); size_t fib_get_size(const fib_t *fib); -void fib_add(fib_t *fib, fib_entry_t *node); +fib_entry_t *fib_add(fib_t *fib, fib_entry_t *node); fib_entry_t *fib_contains(const fib_t *fib, const hicn_prefix_t *prefix); diff --git a/hicn-light/src/hicn/core/fib_entry.c b/hicn-light/src/hicn/core/fib_entry.c index b588e3638..b510b68b4 100644 --- a/hicn-light/src/hicn/core/fib_entry.c +++ b/hicn-light/src/hicn/core/fib_entry.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Copyright (c) 2021-2023 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: @@ -633,6 +633,19 @@ bool fib_entry_has_local_nexthop(const fib_entry_t *entry) { return false; } +bool fib_entry_has_all_local_nexthops(const fib_entry_t *entry) { + connection_table_t *table = forwarder_get_connection_table(entry->forwarder); + + int count = 0; + nexthops_foreach(fib_entry_get_nexthops(entry), nexthop, { + const connection_t *conn = connection_table_at(table, nexthop); + /* Ignore non-local connections */ + if (!connection_is_local(conn)) return false; + count++; + }); + return (count > 0); +} + #ifdef WITH_MAPME void *fib_entry_get_user_data(const fib_entry_t *entry) { diff --git a/hicn-light/src/hicn/core/fib_entry.h b/hicn-light/src/hicn/core/fib_entry.h index b625a33ef..e1e48c871 100644 --- a/hicn-light/src/hicn/core/fib_entry.h +++ b/hicn-light/src/hicn/core/fib_entry.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Copyright (c) 2021-2023 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: @@ -175,12 +175,12 @@ nexthops_t *fib_entry_get_nexthops_from_strategy( /** * @function fib_entry_get_prefix - * @abstract Returns a copy of the prefix. - * @return A reference counted copy that you must destroy + * @return The FIB entry prefix */ const hicn_prefix_t *fib_entry_get_prefix(const fib_entry_t *fib_entry); bool fib_entry_has_local_nexthop(const fib_entry_t *entry); +bool fib_entry_has_all_local_nexthops(const fib_entry_t *entry); #ifdef WITH_MAPME diff --git a/hicn-light/src/hicn/core/forwarder.c b/hicn-light/src/hicn/core/forwarder.c index d0472b520..8c276bfef 100644 --- a/hicn-light/src/hicn/core/forwarder.c +++ b/hicn-light/src/hicn/core/forwarder.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Copyright (c) 2021-2023 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: @@ -32,6 +32,11 @@ /* Batch sending: only if the previous option is undefined */ #define USE_QUEUE true +/* Shall we send mapme updates to advertise all local prefixes on newly created + * faces + */ +//#define ADVERTISE_PREFIXES_ON_NEW_FACES + #ifndef _WIN32 #include #include @@ -250,9 +255,11 @@ void forwarder_on_route_event(const forwarder_t *forwarder, fib_entry_t *entry) { commands_notify_route(forwarder, entry); +#ifdef ADVERTISE_PREFIXES_ON_NEW_FACES nexthops_t new_nexthops = NEXTHOPS_EMPTY; - nexthops_t *nexthops; +#endif /* ADVERTISE_PREFIXES_ON_NEW_FACES */ + nexthops_t *nexthops = NULL; char *prefix_type_s; const connection_table_t *table = @@ -272,6 +279,7 @@ void forwarder_on_route_event(const forwarder_t *forwarder, nexthops = fib_entry_get_nexthops(entry); nexthops_reset(nexthops); fib_entry_filter_nexthops(entry, nexthops, ~0, false); +#ifdef ADVERTISE_PREFIXES_ON_NEW_FACES } else { /* Check available non-local connections (on which we would send MAP-Me * updates */ @@ -281,10 +289,14 @@ void forwarder_on_route_event(const forwarder_t *forwarder, fib_entry_filter_nexthops(entry, nexthops, ~0, true); #ifdef WITH_MAPME - mapme_set_adjacencies(forwarder->mapme, entry, nexthops); + mapme_set_adjacencies(forwarder->mapme, entry, nexthops, NULL); #endif /* WITH_MAPME */ +#endif /* ADVERTISE_PREFIXES_ON_NEW_FACES */ } + if (!nexthops) + return; + if (!fib_entry_nexthops_changed(entry, nexthops)) return; /* Send notification */ @@ -785,12 +797,15 @@ static int _forwarder_get_interest_manifest( hicn_payload_type_t payload_type; HICN_UNUSED(int rc) = hicn_packet_get_payload_type(pkbuf, &payload_type); - assert(rc == HICN_LIB_ERROR_NONE); + // XXX ASSERT HERE !!! + if (rc != HICN_LIB_ERROR_NONE) return -1; + // assert(rc == HICN_LIB_ERROR_NONE); if (payload_type != HPT_MANIFEST) return -1; rc = hicn_packet_get_payload(pkbuf, &payload, payload_size, false); - assert(rc == HICN_LIB_ERROR_NONE); + // assert(rc == HICN_LIB_ERROR_NONE); + if (rc != HICN_LIB_ERROR_NONE) return -1; *int_manifest_header = (interest_manifest_header_t *)payload; @@ -1252,9 +1267,8 @@ bool forwarder_add_or_update_route(forwarder_t *forwarder, assert(rc < MAXSZ_IP_PREFIX); if (rc < 0) return false; - DEBUG("Adding prefix=%s for conn_id=%d", prefix_s, ingress_id); + INFO("Adding prefix=%s for conn_id=%d", prefix_s, ingress_id); - // XXX TODO this should store options too strategy_type_t strategy_type = configuration_get_strategy(config, prefix_s); hicn_prefix_t name_prefix = HICN_PREFIX_EMPTY; @@ -1263,11 +1277,13 @@ bool forwarder_add_or_update_route(forwarder_t *forwarder, fib_entry_t *entry = fib_contains(forwarder->fib, &name_prefix); if (!entry) { entry = fib_entry_create(&name_prefix, strategy_type, NULL, forwarder); - fib_entry_nexthops_add(entry, ingress_id); - fib_add(forwarder->fib, entry); + if (ingress_id != INVALID_FACE_ID) + fib_entry_nexthops_add(entry, ingress_id); + entry = fib_add(forwarder->fib, entry); } else { - fib_entry_nexthops_add(entry, ingress_id); + if (ingress_id != INVALID_FACE_ID) + fib_entry_nexthops_add(entry, ingress_id); } forwarder_on_route_event(forwarder, entry); @@ -1553,7 +1569,7 @@ RETRY: #endif case HICN_PACKET_TYPE_MAPME: - // XXX what about acks ? + INFO("Received MAP-Me packet"); if (!connection_id_is_valid(msgbuf->connection_id)) { char conn_name[SYMBOLIC_NAME_LEN]; int rc = connection_table_get_random_name(table, conn_name); @@ -1568,6 +1584,7 @@ RETRY: ERROR("Could not create new connection"); goto DROP; } + INFO("Created connection upon MAP-Me packet"); msgbuf->connection_id = connection_id; } mapme_process(forwarder->mapme, msgbuf); diff --git a/hicn-light/src/hicn/core/mapme.c b/hicn-light/src/hicn/core/mapme.c index 53c7ec9da..acda2b8cd 100644 --- a/hicn-light/src/hicn/core/mapme.c +++ b/hicn-light/src/hicn/core/mapme.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Copyright (c) 2021-2023 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: @@ -129,7 +129,6 @@ #define MS2NS(x) x * 1000000 #define T2NS(x) forwarder_TicksToNanos(x) -//#define MAPME_ALLOW_NONEXISTING_FIB_ENTRY #define MAPME_DEFAULT_TU 5000 /* ms */ #define MAPME_DEFAULT_RETX 500 /* ms */ #define MAPME_DEFAULT_DISCOVERY false @@ -303,6 +302,7 @@ static void mapme_create_tfib(const mapme_t *mapme, fib_entry_t *entry) { static hicn_mapme_type_t mapme_get_type_from_heuristic(const mapme_t *mapme, fib_entry_t *entry) { #if 0 + if (!entry) return UPDATE; if (fib_entry_has_local_nexthop(entry)) /* We are a producer for this entry, send update */ return UPDATE; @@ -315,43 +315,67 @@ static hicn_mapme_type_t mapme_get_type_from_heuristic(const mapme_t *mapme, * * Here nexthops is not necessarily FIB nexthops as we might advertise given FIB * entries on various other connections. + * + * prefix can be specified to send an update for a More Specific Prefix (MSP), + * or left NULL for the default behaviour. Note there will be no support for + * retransmission for MSP. + * + * NOTES: + * - if the face is pending an we receive an IN, maybe we should not cancel the + * timer + * - this function should never be called for Notifications. */ -/* NOTE: if the face is pending an we receive an IN, maybe we should not cancel - * the timer - */ -// XXX Make sure this function is never called for Notifications -// XXX overall review notification code and integrate it in VPP int mapme_send_to_nexthops(const mapme_t *mapme, fib_entry_t *entry, - const nexthops_t *nexthops) { + const nexthops_t *nexthops, + const hicn_prefix_t *prefix) { + INFO("mapme send to nexthops"); + const hicn_prefix_t *mapme_prefix; + uint32_t mapme_seq; + + assert(!!prefix ^ !!entry); + if (mapme->enabled == false) { WARN("MAP-Me is NOT enabled"); return -1; } - mapme_tfib_t *tfib = TFIB(entry); - if (tfib == NULL) { - mapme_create_tfib(mapme, entry); - tfib = TFIB(entry); + if (prefix) { + INFO("mapme with given prefix"); + mapme_prefix = prefix; + mapme_seq = 1; + } else { + INFO("mapme wih fib entry prefix"); + mapme_tfib_t *tfib = TFIB(entry); + if (tfib == NULL) { + mapme_create_tfib(mapme, entry); + tfib = TFIB(entry); + } + + mapme_prefix = fib_entry_get_prefix(entry); + mapme_seq = tfib->seq; } - const hicn_prefix_t *prefix = fib_entry_get_prefix(entry); + char prefix_s[MAXSZ_IP_PREFIX]; + int rc = hicn_prefix_snprintf(prefix_s, MAXSZ_IP_PREFIX, mapme_prefix); + assert(rc < MAXSZ_IP_PREFIX); + if (rc < 0) NULL; - WITH_DEBUG({ + INFO("mapme send to nexthops prefix= %s", prefix_s); + + WITH_INFO({ char buf[MAXSZ_HICN_PREFIX]; - int rc = hicn_prefix_snprintf(buf, MAXSZ_HICN_PREFIX, prefix); + int rc = hicn_prefix_snprintf(buf, MAXSZ_HICN_PREFIX, mapme_prefix); if (rc < 0 || rc >= MAXSZ_HICN_PREFIX) snprintf(buf, MAXSZ_HICN_PREFIX, "(error)"); - DEBUG("sending IU/IN for name %s on all nexthops", buf); + INFO("sending IU/IN for name %s on nexthops", buf); }) - mapme_params_t params = { - .protocol = mapme->protocol, - .type = mapme_get_type_from_heuristic(mapme, entry), - .seq = tfib->seq, - }; + mapme_params_t params = {.protocol = mapme->protocol, + .type = mapme_get_type_from_heuristic(mapme, entry), + .seq = mapme_seq}; uint8_t packet[MTU]; - size_t size = hicn_mapme_create_packet(packet, prefix, ¶ms); + size_t size = hicn_mapme_create_packet(packet, mapme_prefix, ¶ms); if (size <= 0) { ERROR("Could not create MAP-Me packet"); return -1; @@ -360,8 +384,8 @@ int mapme_send_to_nexthops(const mapme_t *mapme, fib_entry_t *entry, connection_table_t *table = forwarder_get_connection_table(mapme->forwarder); nexthops_foreach(nexthops, nexthop, { - INFO("sending mapme packet on connection %d", nexthop); const connection_t *conn = connection_table_get_by_id(table, nexthop); + assert(!connection_is_local(conn)); connection_send_packet(conn, packet, size); }); @@ -407,34 +431,62 @@ int mapme_set_all_adjacencies(const mapme_t *mapme, fib_entry_t *entry) { nexthops_t *nexthops = fib_entry_get_mapme_nexthops(entry, &new_nexthops); /* We set force to true to avoid overriding the FIB cache */ - return mapme_set_adjacencies(mapme, entry, nexthops); + return mapme_set_adjacencies(mapme, entry, nexthops, NULL); } // XXX this will change with the FIB cache // XXX we are sometimes incrementing tfib seq for nothing int mapme_set_adjacencies(const mapme_t *mapme, fib_entry_t *entry, - nexthops_t *nexthops) { + nexthops_t *nexthops, const hicn_prefix_t *prefix) { + INFO("mapme set adjacenies"); + /* + * - entry is provided in case of a producer reannouncement + * - prefix is provided for control plane triggered updates + */ + assert(!!prefix ^ !!entry); + if (mapme->enabled == false) { WARN("MAP-Me is NOT enabled"); return -1; } - if (!fib_entry_has_local_nexthop(entry)) return -1; + if (entry) { + /* Check disabled, we need to be able to send an update for a larger prefix + * that the one being served. + */ + // if (!fib_entry_has_local_nexthop(entry)) return -1; - /* Advertise prefix on all available next hops (if needed) */ - mapme_tfib_t *tfib = TFIB(entry); - if (tfib == NULL) { - mapme_create_tfib(mapme, entry); - tfib = TFIB(entry); - } + mapme_tfib_t *tfib = TFIB(entry); + if (tfib == NULL) { + mapme_create_tfib(mapme, entry); + tfib = TFIB(entry); + } + + /* + * We need to prevent pending updates to recreate a link which does not make + * since anymore since we edit the graph here. + */ + nexthops_clear(&tfib->nexthops); - nexthops_clear(&tfib->nexthops); - tfib->seq++; + /* We update the sequence number in all cases otherwise this won't allow + * repetition + */ + tfib->seq++; + } - mapme_send_to_nexthops(mapme, entry, nexthops); + INFO("calling send to nh"); + mapme_send_to_nexthops(mapme, entry, nexthops, prefix); return 0; } +int mapme_set_adjacency(const mapme_t *mapme, fib_entry_t *entry, + nexthop_t nexthop, const hicn_prefix_t *prefix) { + nexthops_t nexthops = NEXTHOPS_EMPTY; + nexthops_add(&nexthops, nexthop); + + return mapme_set_adjacencies(mapme, entry, &nexthops, prefix); +} + int mapme_update_adjacencies(const mapme_t *mapme, fib_entry_t *entry, bool inc_iu_seq) { if (mapme->enabled == false) { @@ -450,7 +502,7 @@ int mapme_update_adjacencies(const mapme_t *mapme, fib_entry_t *entry, if (inc_iu_seq) tfib->seq++; - mapme_send_to_nexthops(mapme, entry, &tfib->nexthops); + mapme_send_to_nexthops(mapme, entry, &tfib->nexthops, NULL); return 0; } @@ -464,7 +516,7 @@ int mapme_send_to_nexthop(const mapme_t *mapme, fib_entry_t *entry, nexthops_t nexthops = NEXTHOPS_EMPTY; nexthops_add(&nexthops, nexthop); - return mapme_send_to_nexthops(mapme, entry, &nexthops); + return mapme_send_to_nexthops(mapme, entry, &nexthops, NULL); } #if 0 @@ -525,34 +577,47 @@ void mapme_on_connection_event(const mapme_t *mapme, * Special Interest handling *----------------------------------------------------------------------------*/ -// XXX this code has not been updated -#ifdef MAPME_ALLOW_NONEXISTING_FIB_ENTRY -int mapme_create_fib_entry(const mapme_t *mapme, const Name *name, - unsigned ingress_id) { - INFO(" - Re-creating FIB entry with next hop on connection %d", ingress_id); +#ifdef HICN_MAPME_ALLOW_NONEXISTING_FIB_ENTRY +fib_entry_t *mapme_create_fib_entry(const mapme_t *mapme, + const hicn_prefix_t *prefix, + unsigned ingress_id) { + INFO(" - creating FIB entry with next hop on connection %d", ingress_id); + /* * This might happen for a node hosting a producer which has moved. * Destroying the face has led to removing all corresponding FIB * entries. In that case, we need to correctly restore the FIB entries. + * Also in case we have an intermediate node with just a less specific prefix + * (eg. a default route), and thus an announcement with a more specific + * prefix. In that case we need to perform a FIB lookup to find the next hops + * to which the message should be propagated (before adding). */ - strategy_type fwdStrategy = LAST_STRATEGY_VALUE; + forwarder_t *forwarder = mapme->forwarder; + + fib_t *fib = forwarder_get_fib(forwarder); + configuration_t *config = forwarder_get_configuration(forwarder); + + char prefix_s[MAXSZ_IP_PREFIX]; + int rc = hicn_prefix_snprintf(prefix_s, MAXSZ_IP_PREFIX, prefix); + assert(rc < MAXSZ_IP_PREFIX); + if (rc < 0) NULL; + + INFO("creating FIB entry for prefix %s", prefix_s); + + strategy_type_t strategy_type = configuration_get_strategy(config, prefix_s); + fib_entry_t *entry = fib_entry_create(prefix, strategy_type, NULL, forwarder); + mapme_create_tfib(mapme, entry); + + fib_entry_t *lpm = fib_match_prefix(fib, prefix); + + // Keep this after the LPM lookup + fib_add(fib, entry); - /* - * It might also be due to the announcement of a more specific prefix. In - * that case we need to perform a FIB lookup to find the next hops to which - * the message should be propagated. - */ -#ifdef WITH_POLICY - entry = fib_entry_Create(name, fwdStrategy, mapme->forwarder); -#else - entry = fib_entry_Create(name, fwdStrategy); -#endif /* WITH_POLICY */ - fib_entry_t *lpm = fib_MatchName(fib, name); - fib_Add(fib, entry); if (!lpm) { - TFIB(entry)->seq = seq; - fib_entry_AddNexthop(entry, ingress_id); - return true; + TFIB(entry)->seq = 0; + if (ingress_id != INVALID_FACE_ID) + fib_entry_nexthops_add(entry, ingress_id); + return entry; } /* @@ -560,11 +625,9 @@ int mapme_create_fib_entry(const mapme_t *mapme, const Name *name, * the more specific name, and proceed as usual. Worst case we clone the * default route... */ - const NumberSet *lpm_nexthops = fib_entry_nexthops_get(lpm); - for (size_t i = 0; i < numberSet_Length(lpm_nexthops); i++) { - fib_entry_AddNexthop(entry, numberSet_GetItem(lpm_nexthops, i)); - } - return 0; + const nexthops_t *lpm_nexthops = fib_entry_get_nexthops(lpm); + nexthops_foreach(lpm_nexthops, nh, { fib_entry_nexthops_add(entry, nh); }); + return entry; } #endif @@ -797,13 +860,13 @@ static void mapme_on_interest(mapme_t *mapme, msgbuf_t *msgbuf, msgbuf_pool_put(msgbuf_pool, ack); - WITH_DEBUG({ + WITH_INFO({ char buf[MAXSZ_HICN_PREFIX]; int rc = hicn_prefix_snprintf(buf, MAXSZ_HICN_PREFIX, prefix); if (rc < 0 || rc >= MAXSZ_HICN_PREFIX) snprintf(buf, MAXSZ_HICN_PREFIX, "%s", "(error)"); - DEBUG("Ack'ed interest : connection=%d prefix=%s seq=%d", ingress_id, buf, - params->seq); + INFO("Ack'ed interest : connection=%d prefix=%s seq=%d", ingress_id, buf, + params->seq); }); /* EPM on FIB */ @@ -811,7 +874,8 @@ static void mapme_on_interest(mapme_t *mapme, msgbuf_t *msgbuf, fib_entry_t *entry = fib_contains(fib, prefix); if (!entry) { #ifdef HICN_MAPME_ALLOW_NONEXISTING_FIB_ENTRY - if (mapme_create_fib_entry(mapme, &name, ingress_id) < 0) { + entry = mapme_create_fib_entry(mapme, prefix, ingress_id); + if (!entry) { ERROR("Failed to create FIB entry"); return; } @@ -836,7 +900,13 @@ static void mapme_on_interest(mapme_t *mapme, msgbuf_t *msgbuf, * for which the prefix has a local next hop in the FIB. */ // XXX NOT IN VPP ? - if (fib_entry_has_local_nexthop(entry)) { + + /* Initially we were detecting that the update completed when it returned to + * the producer, Because there might be proxies (using local/remote strategy), + * we need instead to verify if there is no non-local faces. + */ + + if (fib_entry_has_all_local_nexthops(entry)) { INFO("Received original interest... Update complete"); return; } @@ -856,12 +926,24 @@ static void mapme_on_interest(mapme_t *mapme, msgbuf_t *msgbuf, * * This could might optimized for situations where nothing changes, but * this is very unlikely if not impossible... - * */ - nexthops_foreach(&entry->nexthops, prevhop, - { nexthops_add(&tfib->nexthops, prevhop); }); + */ + nexthops_t nexthops_keep = NEXTHOPS_EMPTY; + nexthops_foreach(&entry->nexthops, prevhop, { + const connection_t *conn = connection_table_get_by_id(table, prevhop); + /* Preserve local connections, migrate others to TFIB */ + if (connection_is_local(conn)) { + nexthops_add(&nexthops_keep, prevhop); + } else { + nexthops_add(&tfib->nexthops, prevhop); + } + }); + nexthops_remove(&tfib->nexthops, ingress_id); + nexthops_clear(&entry->nexthops); nexthops_add(&entry->nexthops, ingress_id); + nexthops_foreach(&nexthops_keep, nh, + { nexthops_add(&entry->nexthops, nh); }); event = MAPME_EVENT_NH_SET; @@ -899,8 +981,8 @@ static void mapme_on_interest(mapme_t *mapme, msgbuf_t *msgbuf, params->seq, tfib->seq, ingress_id); return; } else { - DEBUG("Received seq %d < fib_seq %d, sending backwards on face %d", - params->seq, tfib->seq, ingress_id); + INFO("Received seq %d < fib_seq %d, sending backwards on face %d", + params->seq, tfib->seq, ingress_id); nexthops_add(&tfib->nexthops, ingress_id); } @@ -916,13 +998,13 @@ static void mapme_on_interest(mapme_t *mapme, msgbuf_t *msgbuf, static void mapme_on_data(mapme_t *mapme, msgbuf_t *msgbuf, unsigned ingress_id, hicn_prefix_t *prefix, mapme_params_t *params) { - WITH_DEBUG({ + WITH_INFO({ char buf[MAXSZ_HICN_PREFIX]; int rc = hicn_prefix_snprintf(buf, MAXSZ_HICN_PREFIX, prefix); if (rc < 0 || rc >= MAXSZ_HICN_PREFIX) snprintf(buf, MAXSZ_HICN_PREFIX, "(error)"); - DEBUG("Received ack for name prefix=%s seq=%d on conn id=%d", buf, - params->seq, ingress_id); + INFO("Received ack for name prefix=%s seq=%d on conn id=%d", buf, + params->seq, ingress_id); }) const fib_t *fib = forwarder_get_fib(mapme->forwarder); @@ -979,8 +1061,8 @@ void mapme_process(mapme_t *mapme, msgbuf_t *msgbuf) { if (rc < 0) return; // XXX TYPE STR - DEBUG("Received interest type: %d seq: %d len:%d", params.type, params.seq, - prefix.len); + INFO("Received interest type: %d seq: %d len:%d", params.type, params.seq, + prefix.len); // XXX RENAME TYPES switch (params.type) { diff --git a/hicn-light/src/hicn/core/mapme.h b/hicn-light/src/hicn/core/mapme.h index 188607421..9ece8a090 100644 --- a/hicn-light/src/hicn/core/mapme.h +++ b/hicn-light/src/hicn/core/mapme.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Cisco and/or its affiliates. + * Copyright (c) 2021-2023 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: @@ -33,6 +33,10 @@ #include "fib_entry.h" #include "msgbuf.h" +// Allow processing of MAP-Me requests when no FIB entry is present. +// An alternative would be to perform a LPM +#define HICN_MAPME_ALLOW_NONEXISTING_FIB_ENTRY + typedef struct mapme_s mapme_t; /** @@ -85,9 +89,24 @@ int mapme_set_all_adjacencies(const mapme_t *mapme, fib_entry_t *entry); * @param [in] mapme - Pointer to the MAP-Me data structure. * @param [in] fib_entry - The FIB entry to consider * @param [in] nexthops - next hops on which to send the update. + * @param [in] prefix - A more specific prefix (special use with no retx), or + * NULL */ int mapme_set_adjacencies(const mapme_t *mapme, fib_entry_t *entry, - nexthops_t *nexthops); + nexthops_t *nexthops, const hicn_prefix_t *prefix); + +/** + * @function mapme_set_adjacencies + * @abstract sends an update to the specified adjacency. Used by control plane + * commands. + * @param [in] mapme - Pointer to the MAP-Me data structure. + * @param [in] fib_entry - The FIB entry to consider + * @param [in] nexthop - nexthop on which to send the update. + * @param [in] prefix - A more specific prefix (special use with no retx), or + * NULL + */ +int mapme_set_adjacency(const mapme_t *mapme, fib_entry_t *entry, + nexthop_t nexthop, const hicn_prefix_t *prefix); /** * @function mapme_update_adjacencies @@ -122,6 +141,12 @@ void mapme_on_connection_event(const mapme_t *mapme, const connection_t *conn, // nexthops_t * mapme_get_nexthops(const mapme_t *mapme, fib_entry_t *fib_entry, // const msgbuf_t *interest); +#ifdef HICN_MAPME_ALLOW_NONEXISTING_FIB_ENTRY +fib_entry_t *mapme_create_fib_entry(const mapme_t *mapme, + const hicn_prefix_t *prefix, + unsigned ingress_id); +#endif /* HICN_MAPME_ALLOW_NONEXISTING_FIB_ENTRY */ + void mapme_set_enable(mapme_t *mapme, bool enable); void mapme_set_discovery(mapme_t *mapme, bool enable); void mapme_set_timescale(mapme_t *mapme, uint32_t time); diff --git a/hicn-light/src/hicn/core/msgbuf.h b/hicn-light/src/hicn/core/msgbuf.h index ef2b38c51..7a35929f4 100644 --- a/hicn-light/src/hicn/core/msgbuf.h +++ b/hicn-light/src/hicn/core/msgbuf.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Copyright (c) 2021-2023 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: @@ -111,8 +111,7 @@ static inline u32 msgbuf_get_name_hash(const msgbuf_t *msgbuf) { static inline u32 msgbuf_get_interest_lifetime(const msgbuf_t *msgbuf) { u32 lifetime; int rc = hicn_interest_get_lifetime(msgbuf_get_pkbuf(msgbuf), &lifetime); - assert(rc == HICN_LIB_ERROR_NONE); // XXX - _unused(rc); + if (rc != HICN_LIB_ERROR_NONE) return 0; return lifetime; } @@ -130,8 +129,7 @@ static inline bool msgbuf_set_interest_lifetime(msgbuf_t *msgbuf, static inline u32 msgbuf_get_data_expiry_time(const msgbuf_t *msgbuf) { u32 lifetime; int rc = hicn_data_get_expiry_time(msgbuf_get_pkbuf(msgbuf), &lifetime); - assert(rc == HICN_LIB_ERROR_NONE); // XXX - _unused(rc); + if (rc != HICN_LIB_ERROR_NONE) return 0; return lifetime; } diff --git a/hicn-light/src/hicn/strategies/local_prefixes.c b/hicn-light/src/hicn/strategies/local_prefixes.c index 25927ac69..fb161ab2a 100644 --- a/hicn-light/src/hicn/strategies/local_prefixes.c +++ b/hicn-light/src/hicn/strategies/local_prefixes.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Cisco and/or its affiliates. + * Copyright (c) 2021-2023 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: @@ -77,6 +77,6 @@ void update_remote_node_paths(const void *nexthops, const void *forwarder, fib_entry_t *entry = fib_match_prefix(fib, &prefixes->local_prefixes[i]); if (!entry) continue; // XXX we don't want to force - mapme_set_adjacencies(mapme, entry, (nexthops_t *)nexthops); + mapme_set_adjacencies(mapme, entry, (nexthops_t *)nexthops, NULL); } } diff --git a/lib/src/protocol/icmp.c b/lib/src/protocol/icmp.c index 5ee70f088..add871bcf 100644 --- a/lib/src/protocol/icmp.c +++ b/lib/src/protocol/icmp.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Cisco and/or its affiliates. + * Copyright (c) 2021-2023 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: @@ -177,7 +177,8 @@ int icmp_get_type (const hicn_packet_buffer_t *pkbuf, const size_t pos, hicn_packet_type_t *type) { - return CALL_CHILD (get_type, pkbuf, pos, type); + *type = HICN_PACKET_TYPE_MAPME; + return HICN_LIB_ERROR_NONE; } int diff --git a/libtransport/src/io_modules/hicn-light/hicn_forwarder_module.cc b/libtransport/src/io_modules/hicn-light/hicn_forwarder_module.cc index 0d45ba49d..98bd42fb5 100644 --- a/libtransport/src/io_modules/hicn-light/hicn_forwarder_module.cc +++ b/libtransport/src/io_modules/hicn-light/hicn_forwarder_module.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Cisco and/or its affiliates. + * Copyright (c) 2021-2023 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: @@ -218,20 +218,16 @@ utils::MemBuf::Ptr HicnForwarderModule::createCommandDeleteConnection() { utils::MemBuf::Ptr HicnForwarderModule::createCommandMapmeSendUpdate() { auto ret = PacketManager<>::getInstance().getMemBuf(); - auto command = - reinterpret_cast(ret->writableData()); - ret->append(sizeof(msg_mapme_send_update_t)); + auto command = reinterpret_cast(ret->writableData()); + ret->append(sizeof(msg_mapme_add_t)); std::memset(command, 0, sizeof(*command)); - *command = { - .header = - { - .message_type = REQUEST_LIGHT, - .command_id = COMMAND_TYPE_MAPME_SEND_UPDATE, - .length = 1, - .seq_num = seq_++, - }, - }; + *command = {.header = { + .message_type = REQUEST_LIGHT, + .command_id = COMMAND_TYPE_MAPME_ADD, + .length = 1, + .seq_num = seq_++, + }}; return ret; } -- cgit 1.2.3-korg