summaryrefslogtreecommitdiffstats
path: root/ctrl/libhicnctrl/src/objects
diff options
context:
space:
mode:
authorLuca Muscariello <muscariello@ieee.org>2022-08-04 16:06:34 +0200
committerLuca Muscariello <muscariello@ieee.org>2022-08-04 16:31:51 +0200
commit6d22a0db96aa7f8e3102ae44d00c09e36a2e9c57 (patch)
tree79546bbf09f6fbf74db7bc89117843f06ce937ea /ctrl/libhicnctrl/src/objects
parent012843b1c0bc0838e69085ed83a79ec8b6f97360 (diff)
feat: Due to the deep modifications related to names and packet format,
this task cover a large part of the codebase and involves several changes: - the library provides a name data structure (hicn_name_t ), which is composed of a name prefix (hicn_name_prefix_t) and a name suffix (hicn_name_suffix_t), and it has been extended to provide all support functions required for name manipulation, including common prefix computation, as required for the Longest Prefix Match (LPM)in the forwarder, in addition to Exact Prefix Match (EPM). - all code has been rewritten to use this data structure instead of having for instance the forwarder define its own name class (used to be Name and NameBitVector) the code has been refactored to minimize name allocations and copies, one remaining aspect is the difference of name storage between PIT and CS entries (respectively in the PIT entry, and in the message buffer), which causes the packet cache index to be updated when a PIT entry is converted into a CS entry. By storing the name in the PIT/CS entry everytime, we might save on this operation). - hicn-light FIB has been rewritten : code has been refactored and should now be shorter and documented; unit tests have been drafted but more would be required to cover all cases and match the algorithms to add/remove nodes, as specified in the doc. all protocol details and hICN header formats are now abstracted by the library for the forwarder (and thus header.h and  protocols/*.h have been removed from public includes, and replaced by packet.h providing protocol agnostic packet level functions, completely replacing the compat.h header that used to provide similar functions. - this works by exposing a opaque buffer to the application (a kind of socket buffer) which is used by the lib to cache the packet format and offsets of the different layers in the buffer and provider efficient operations (the packet format is either defined for packet construction, or guessed at ingress, and this structure is updated accordingly only once). Co-authored-by: Jordan Augé <jordan.auge+fdio@cisco.com> Signed-off-by: Luca Muscariello <muscariello@ieee.org> Change-Id: I31e321897f85f0267fe8ba4720363c180564492f
Diffstat (limited to 'ctrl/libhicnctrl/src/objects')
-rw-r--r--ctrl/libhicnctrl/src/objects/active_interface.c86
-rw-r--r--ctrl/libhicnctrl/src/objects/active_interface.h28
-rw-r--r--ctrl/libhicnctrl/src/objects/base.c34
-rw-r--r--ctrl/libhicnctrl/src/objects/base.h27
-rw-r--r--ctrl/libhicnctrl/src/objects/connection.c289
-rw-r--r--ctrl/libhicnctrl/src/objects/connection.h31
-rw-r--r--ctrl/libhicnctrl/src/objects/face.c174
-rw-r--r--ctrl/libhicnctrl/src/objects/face.h30
-rw-r--r--ctrl/libhicnctrl/src/objects/listener.c203
-rw-r--r--ctrl/libhicnctrl/src/objects/listener.h30
-rw-r--r--ctrl/libhicnctrl/src/objects/route.c173
-rw-r--r--ctrl/libhicnctrl/src/objects/route.h30
-rw-r--r--ctrl/libhicnctrl/src/objects/stats.c59
-rw-r--r--ctrl/libhicnctrl/src/objects/strategy.c92
-rw-r--r--ctrl/libhicnctrl/src/objects/strategy.h29
-rw-r--r--ctrl/libhicnctrl/src/objects/subscription.c94
-rw-r--r--ctrl/libhicnctrl/src/objects/subscription.h28
17 files changed, 1437 insertions, 0 deletions
diff --git a/ctrl/libhicnctrl/src/objects/active_interface.c b/ctrl/libhicnctrl/src/objects/active_interface.c
new file mode 100644
index 000000000..796123963
--- /dev/null
+++ b/ctrl/libhicnctrl/src/objects/active_interface.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2021-2022 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 active_interface.c
+ * \brief Implementation of active_interface object.
+ */
+
+#include <hicn/ctrl/api.h>
+#include <hicn/ctrl/object.h>
+#include <hicn/ctrl/objects/active_interface.h>
+#include <hicn/util/log.h>
+#include <hicn/util/ip_address.h>
+
+#include "../object_private.h"
+#include "../object_vft.h"
+
+/* ACTIVE_INTERFACE VALIDATE */
+
+int hc_active_interface_validate(const hc_active_interface_t *active_interface,
+ bool allow_partial) {
+ return 0; // XXX TODO
+}
+
+int _hc_active_interface_validate(const hc_object_t *object,
+ bool allow_partial) {
+ return hc_active_interface_validate(&object->active_interface, allow_partial);
+}
+
+/* ACTIVE_INTERFACE CMP */
+
+// XXX TODO
+int hc_active_interface_cmp(const hc_active_interface_t *active_interface1,
+ const hc_active_interface_t *active_interface2) {
+ return -1;
+}
+
+int _hc_active_interface_cmp(const hc_object_t *object1,
+ const hc_object_t *object2) {
+ return hc_active_interface_cmp(&object1->active_interface,
+ &object2->active_interface);
+}
+
+/* ACTIVE_INTERFACE SNPRINTF */
+
+/* /!\ Please update constants in header file upon changes */
+int hc_active_interface_snprintf(
+ char *s, size_t size, const hc_active_interface_t *active_interface) {
+ int rc;
+ char *pos = s;
+
+ rc = hicn_ip_prefix_snprintf(pos, size, &active_interface->prefix);
+ if ((rc < 0) || (rc >= size)) return rc;
+ pos += rc;
+ size -= rc;
+
+ for (netdevice_type_t type = NETDEVICE_TYPE_UNDEFINED + 1;
+ type < NETDEVICE_TYPE_N; type++) {
+ if (!netdevice_flags_has(active_interface->interface_types, type)) continue;
+ rc = snprintf(pos, size, " %s", netdevice_type_str(type));
+ if ((rc < 0) || (rc >= size)) return (int)(pos - s + rc);
+
+ pos += rc;
+ size -= rc;
+ }
+ return (int)(pos - s);
+}
+
+int _hc_active_interface_snprintf(char *s, size_t size,
+ const hc_object_t *object) {
+ return hc_active_interface_snprintf(s, size, &object->active_interface);
+}
+
+DECLARE_OBJECT_OPS(OBJECT_TYPE_ACTIVE_INTERFACE, active_interface);
diff --git a/ctrl/libhicnctrl/src/objects/active_interface.h b/ctrl/libhicnctrl/src/objects/active_interface.h
new file mode 100644
index 000000000..973b08e40
--- /dev/null
+++ b/ctrl/libhicnctrl/src/objects/active_interface.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2021-2022 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 active_interface.h
+ * \brief Route.
+ */
+
+#ifndef HICNCTRL_IMPL_OBJECTS_ACTIVE_INTERFACE_H
+#define HICNCTRL_IMPL_OBJECTS_ACTIVE_INTERFACE_H
+
+#include "../object_vft.h"
+
+DECLARE_OBJECT_OPS_H(OBJECT_TYPE_ACTIVE_INTERFACE, active_interface);
+
+#endif /* HICNCTRL_IMPL_OBJECTS_ACTIVE_INTERFACE_H */
diff --git a/ctrl/libhicnctrl/src/objects/base.c b/ctrl/libhicnctrl/src/objects/base.c
new file mode 100644
index 000000000..86e4bfb72
--- /dev/null
+++ b/ctrl/libhicnctrl/src/objects/base.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2022 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 base.c
+ * \brief Implementation of base functions for object APIs.
+ */
+
+#include <stdbool.h>
+
+#include "base.h"
+
+#include <hicn/util/log.h>
+
+bool iszero(const void *ptr, int bytes) {
+ char *bptr = (char *)ptr;
+ while (bytes--)
+ if (*bptr++) return false;
+ return true;
+}
+
+bool isempty(const char *str) { return str[0] == '\0'; }
diff --git a/ctrl/libhicnctrl/src/objects/base.h b/ctrl/libhicnctrl/src/objects/base.h
new file mode 100644
index 000000000..eb85483e9
--- /dev/null
+++ b/ctrl/libhicnctrl/src/objects/base.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2022 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 base.h
+ * \brief Base functions for object APIs.
+ */
+
+#ifndef HICNCTRL_OBJECTS_BASE_H
+#define HICNCTRL_OBJECTS_BASE_H
+
+bool iszero(const void *ptr, int bytes);
+bool isempty(const char *str);
+
+#endif /* HICNCTRL_OBJECTS_BASE_H */
diff --git a/ctrl/libhicnctrl/src/objects/connection.c b/ctrl/libhicnctrl/src/objects/connection.c
new file mode 100644
index 000000000..14e763396
--- /dev/null
+++ b/ctrl/libhicnctrl/src/objects/connection.c
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2021-2022 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 connection.c
+ * \brief Implementation of connection object.
+ */
+
+#include <assert.h>
+
+#include <hicn/ctrl/api.h>
+#include <hicn/ctrl/object.h>
+#include <hicn/ctrl/objects/connection.h>
+#include <hicn/util/log.h>
+
+#include "../object_private.h"
+#include "../object_vft.h"
+#include "base.h"
+
+bool hc_connection_is_local(const hc_connection_t *connection) {
+ return (strncmp(connection->interface_name, "lo", INTERFACE_LEN) == 0);
+}
+
+bool hc_connection_has_local(const hc_connection_t *connection) {
+ assert(connection);
+ return IS_VALID_PORT(connection->local_port) &&
+ IS_VALID_ADDRESS(connection->local_addr);
+}
+
+/* CONNECTION VALIDATE */
+
+int hc_connection_validate(const hc_connection_t *connection,
+ bool allow_partial) {
+ int has_id = 0;
+ int has_name = 0;
+ int has_interface_name = 0;
+ int has_netdevice_type = 0;
+ int has_type = 0;
+ int has_family = 0;
+ int has_local_addr = 0;
+ int has_local_port = 0;
+ int has_remote_addr = 0;
+ int has_remote_port = 0;
+ int has_admin_state = 0;
+ int has_priority = 0;
+ int has_tags = 0;
+ int has_state = 0;
+
+ if (connection->id == ~0) {
+ ERROR("[hc_listener_validate] Invalid id specified");
+ return -1;
+ }
+ has_id = 1;
+
+ if (!isempty(connection->name)) {
+ if (!IS_VALID_NAME(connection->name)) {
+ ERROR("[hc_connection_validate] Invalid name specified");
+ return -1;
+ }
+ has_name = 1;
+ }
+
+ if (!isempty(connection->interface_name)) {
+ if (!IS_VALID_INTERFACE_NAME(connection->interface_name)) {
+ ERROR("[hc_connection_validate] Invalid interface_name specified");
+ return -1;
+ }
+ has_interface_name = 1;
+ }
+
+ if (connection->type != FACE_TYPE_UNDEFINED) {
+ if (!IS_VALID_TYPE(connection->type)) {
+ ERROR("[hc_connection_validate] Invalid type specified");
+ return -1;
+ }
+ has_type = 1;
+ }
+
+ if (connection->family != AF_UNSPEC) {
+ if (!IS_VALID_FAMILY(connection->family)) {
+ ERROR("[hc_connection_validate] Invalid family specified");
+ return -1;
+ }
+ has_family = 1;
+ }
+
+ if (!hicn_ip_address_empty(&connection->local_addr)) {
+ if (!IS_VALID_ADDRESS(connection->local_addr)) {
+ ERROR("[hc_connection_validate] Invalid local_addr specified");
+ return -1;
+ }
+ has_local_addr = 1;
+ }
+
+ if (connection->local_port != 0) {
+ if (!IS_VALID_PORT(connection->local_port)) {
+ ERROR("[hc_connection_validate] Invalid local_port specified");
+ return -1;
+ }
+ has_local_port = 1;
+ }
+
+ if (!hicn_ip_address_empty(&connection->remote_addr)) {
+ if (!IS_VALID_ADDRESS(connection->remote_addr)) {
+ ERROR("[hc_connection_validate] Invalid remote_addr specified");
+ return -1;
+ }
+ has_remote_addr = 1;
+ }
+
+ if (connection->remote_port != 0) {
+ if (!IS_VALID_PORT(connection->remote_port)) {
+ ERROR("[hc_connection_validate] Invalid remote_port specified");
+ return -1;
+ }
+ has_remote_port = 1;
+ }
+
+ int has_key = has_id || has_name;
+ int has_mandatory_attributes = has_interface_name && has_type && has_family &&
+ has_local_addr && has_local_port &&
+ has_remote_addr && has_remote_port;
+ int has_optional_attributes =
+ has_netdevice_type && has_admin_state && has_state;
+ has_optional_attributes = has_optional_attributes && has_priority && has_tags;
+
+ if (allow_partial) {
+ if (has_key && !has_mandatory_attributes && !has_optional_attributes)
+ return 0;
+ else if (has_mandatory_attributes)
+ return 0;
+ else
+ return -1;
+ } else {
+ if (has_key && has_mandatory_attributes) return 0;
+ return -1;
+ }
+}
+
+int _hc_connection_validate(const hc_object_t *object, bool allow_partial) {
+ return hc_connection_validate(&object->connection, allow_partial);
+}
+
+/* CONNECTION CMP */
+
+/*
+ * hICN light uses ports even for hICN connections, but their value is
+ * ignored. As connections are specific to hicn-light, we can safely use IP
+ * and ports for comparison independently of the face type.
+ */
+int hc_connection_cmp(const hc_connection_t *c1, const hc_connection_t *c2) {
+ int rc;
+
+ rc = INT_CMP(c1->type, c2->type);
+ if (rc != 0) return rc;
+
+ rc = INT_CMP(c1->family, c2->family);
+ if (rc != 0) return rc;
+
+ rc = strncmp(c1->interface_name, c2->interface_name, INTERFACE_LEN);
+ if (rc != 0) return rc;
+
+ rc = hicn_ip_address_cmp(&c1->local_addr, &c2->local_addr);
+ if (rc != 0) return rc;
+
+ rc = INT_CMP(c1->local_port, c2->local_port);
+ if (rc != 0) return rc;
+
+ rc = hicn_ip_address_cmp(&c1->remote_addr, &c2->remote_addr);
+ if (rc != 0) return rc;
+
+ rc = INT_CMP(c1->remote_port, c2->remote_port);
+ if (rc != 0) return rc;
+
+ return rc;
+}
+
+int _hc_connection_cmp(const hc_object_t *object1, const hc_object_t *object2) {
+ return hc_connection_cmp(&object1->connection, &object2->connection);
+}
+
+/* CONNECTION SNPRINTF */
+
+/* /!\ Please update constants in header file upon changes */
+int hc_connection_snprintf(char *s, size_t size,
+ const hc_connection_t *connection) {
+ char local[MAXSZ_URL];
+ char remote[MAXSZ_URL];
+ int rc;
+
+ // assert(connection->connection_state)
+ if (strcmp(connection->name, "SELF") == 0) {
+ return snprintf(s, size, "%s", connection->name);
+ }
+
+ rc = url_snprintf(local, MAXSZ_URL, &connection->local_addr,
+ connection->local_port);
+ if (rc >= MAXSZ_URL)
+ WARN("[hc_connection_snprintf] Unexpected truncation of URL string");
+ if (rc < 0) return rc;
+ rc = url_snprintf(remote, MAXSZ_URL, &connection->remote_addr,
+ connection->remote_port);
+ if (rc >= MAXSZ_URL)
+ WARN("[hc_connection_snprintf] Unexpected truncation of URL string");
+ if (rc < 0) return rc;
+
+ return snprintf(s, size, "%s %s %s %s", connection->name, local, remote,
+ face_type_str(connection->type));
+}
+
+int _hc_connection_snprintf(char *s, size_t size, const hc_object_t *object) {
+ return hc_connection_snprintf(s, size, &object->connection);
+}
+
+int hc_connection_create(hc_sock_t *s, hc_connection_t *connection) {
+ hc_object_t object;
+ memset(&object, 0, sizeof(hc_object_t));
+ object.connection = *connection;
+ return hc_execute(s, ACTION_CREATE, OBJECT_TYPE_CONNECTION, &object, NULL);
+}
+
+int hc_connection_get(hc_sock_t *s, hc_connection_t *connection,
+ hc_data_t **pdata) {
+ hc_object_t object;
+ memset(&object, 0, sizeof(hc_object_t));
+ object.connection = *connection;
+ return hc_execute(s, ACTION_GET, OBJECT_TYPE_CONNECTION, &object, pdata);
+}
+
+int hc_connection_delete(hc_sock_t *s, hc_connection_t *connection) {
+ hc_object_t object;
+ memset(&object, 0, sizeof(hc_object_t));
+ object.connection = *connection;
+ return hc_execute(s, ACTION_DELETE, OBJECT_TYPE_CONNECTION, &object, NULL);
+}
+
+int hc_connection_list(hc_sock_t *s, hc_data_t **pdata) {
+ return hc_execute(s, ACTION_LIST, OBJECT_TYPE_CONNECTION, NULL, pdata);
+}
+
+int hc_connection_set_admin_state(hc_sock_t *s, const char *conn_id_or_name,
+ face_state_t state) {
+ hc_object_t object;
+ memset(&object, 0, sizeof(hc_object_t));
+ int rc = snprintf(object.connection.name, SYMBOLIC_NAME_LEN, "%s",
+ conn_id_or_name);
+ if (rc < 0 || rc >= SYMBOLIC_NAME_LEN) return -1;
+ object.connection.admin_state = state;
+ return hc_execute(s, ACTION_UPDATE, OBJECT_TYPE_CONNECTION, &object, NULL);
+}
+
+int hc_connection_set_priority(hc_sock_t *s, const char *conn_id_or_name,
+ uint32_t priority) {
+ hc_object_t object;
+ memset(&object, 0, sizeof(hc_object_t));
+ int rc = snprintf(object.connection.name, SYMBOLIC_NAME_LEN, "%s",
+ conn_id_or_name);
+ if (rc < 0 || rc >= SYMBOLIC_NAME_LEN) return -1;
+ object.connection.priority = priority;
+ return hc_execute(s, ACTION_UPDATE, OBJECT_TYPE_CONNECTION, &object, NULL);
+}
+
+int hc_connection_set_tags(hc_sock_t *s, const char *conn_id_or_name,
+
+ policy_tags_t tags) {
+ hc_object_t object;
+ memset(&object, 0, sizeof(hc_object_t));
+ int rc = snprintf(object.connection.name, SYMBOLIC_NAME_LEN, "%s",
+ conn_id_or_name);
+ if (rc < 0 || rc >= SYMBOLIC_NAME_LEN) return -1;
+ object.connection.tags = tags;
+ return hc_execute(s, ACTION_UPDATE, OBJECT_TYPE_CONNECTION, &object, NULL);
+}
+
+GENERATE_FIND(connection);
+
+DECLARE_OBJECT_OPS(OBJECT_TYPE_CONNECTION, connection);
diff --git a/ctrl/libhicnctrl/src/objects/connection.h b/ctrl/libhicnctrl/src/objects/connection.h
new file mode 100644
index 000000000..4a4c78f09
--- /dev/null
+++ b/ctrl/libhicnctrl/src/objects/connection.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2021-2022 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 connection.h
+ * \brief Connection.
+ */
+
+#ifndef HICNCTRL_IMPL_OBJECTS_CONNECTION_H
+#define HICNCTRL_IMPL_OBJECTS_CONNECTION_H
+
+#include "../object_vft.h"
+
+bool hc_connection_is_local(const hc_connection_t *connection);
+bool hc_connection_has_local(const hc_connection_t *connection);
+
+DECLARE_OBJECT_OPS_H(OBJECT_TYPE_CONNECTION, connection);
+
+#endif /* HICNCTRL_IMPL_OBJECTS_CONNECTION_H */
diff --git a/ctrl/libhicnctrl/src/objects/face.c b/ctrl/libhicnctrl/src/objects/face.c
new file mode 100644
index 000000000..c535ff4c5
--- /dev/null
+++ b/ctrl/libhicnctrl/src/objects/face.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2021-2022 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 face.c
+ * \brief Implementation of face object.
+ */
+
+#include <hicn/ctrl/api.h>
+#include <hicn/ctrl/object.h>
+#include <hicn/ctrl/objects/face.h>
+#include <hicn/util/log.h>
+
+#include "../object_private.h"
+#include "../object_vft.h"
+
+bool hc_face_has_netdevice(const hc_face_t *face) {
+ return netdevice_is_empty(&face->netdevice);
+}
+
+/* FACE VALIDATE */
+
+int hc_face_validate(const hc_face_t *face, bool allow_partial) {
+ if ((!allow_partial || !hc_face_has_netdevice(face)) &&
+ !IS_VALID_INTERFACE_NAME(face->interface_name)) {
+ ERROR("[hc_face_validate] Invalid interface_name specified");
+ return -1;
+ }
+ if (!IS_VALID_TYPE(face->type)) {
+ ERROR("[hc_face_validate] Invalid type specified");
+ return -1;
+ }
+ if ((!allow_partial || face->family != AF_UNSPEC) &&
+ !IS_VALID_FAMILY(face->family)) {
+ ERROR("[hc_face_validate] Invalid family specified");
+ return -1;
+ }
+ if ((!allow_partial || !hicn_ip_address_empty(&face->local_addr)) &&
+ !IS_VALID_ADDRESS(face->local_addr)) {
+ ERROR("[hc_face_validate] Invalid local_addr specified");
+ return -1;
+ }
+ if ((!allow_partial || !(face->local_port == 0)) &&
+ !IS_VALID_PORT(face->local_port)) {
+ ERROR("[hc_face_validate] Invalid local_port specified");
+ return -1;
+ }
+ if (!IS_VALID_ADDRESS(face->remote_addr)) {
+ ERROR("[hc_face_validate] Invalid remote_addr specified");
+ return -1;
+ }
+ if (!IS_VALID_PORT(face->remote_port)) {
+ ERROR("[hc_face_validate] Invalid remote_port specified");
+ return -1;
+ }
+ return 0;
+}
+
+int _hc_face_validate(const hc_object_t *object, bool allow_partial) {
+ return hc_face_validate(&object->face, allow_partial);
+}
+
+/* FACE CMP */
+
+int hc_face_cmp(const hc_face_t *c1, const hc_face_t *c2) {
+ return -99; // Not implemented
+}
+
+int _hc_face_cmp(const hc_object_t *object1, const hc_object_t *object2) {
+ return hc_face_cmp(&object1->face, &object2->face);
+}
+
+/* FACE SNPRINTF */
+
+/* /!\ Please update constants in header file upon changes */
+int hc_face_snprintf(char *s, size_t size, const hc_face_t *face) {
+ /* URLs are also big enough to contain IP addresses in the hICN case */
+ char local[MAXSZ_URL];
+ char remote[MAXSZ_URL];
+ char tags[MAXSZ_POLICY_TAGS];
+ int rc;
+
+ switch (face->type) {
+ case FACE_TYPE_HICN:
+ case FACE_TYPE_HICN_LISTENER:
+ rc = hicn_ip_address_snprintf(local, MAXSZ_URL, &face->local_addr);
+ if (rc >= MAXSZ_URL)
+ WARN("[hc_face_snprintf] Unexpected truncation of URL string");
+ if (rc < 0) return rc;
+ rc = hicn_ip_address_snprintf(remote, MAXSZ_URL, &face->remote_addr);
+ if (rc >= MAXSZ_URL)
+ WARN("[hc_face_snprintf] Unexpected truncation of URL string");
+ if (rc < 0) return rc;
+ break;
+ case FACE_TYPE_TCP:
+ case FACE_TYPE_UDP:
+ case FACE_TYPE_TCP_LISTENER:
+ case FACE_TYPE_UDP_LISTENER:
+ rc = url_snprintf(local, MAXSZ_URL, &face->local_addr, face->local_port);
+ if (rc >= MAXSZ_URL)
+ WARN("[hc_face_snprintf] Unexpected truncation of URL string");
+ if (rc < 0) return rc;
+ rc = url_snprintf(remote, MAXSZ_URL, &face->remote_addr,
+ face->remote_port);
+ if (rc >= MAXSZ_URL)
+ WARN("[hc_face_snprintf] Unexpected truncation of URL string");
+ if (rc < 0) return rc;
+ break;
+ default:
+ return -1;
+ }
+
+ // [#ID NAME] TYPE LOCAL_URL REMOTE_URL STATE/ADMIN_STATE (TAGS)
+ rc = policy_tags_snprintf(tags, MAXSZ_POLICY_TAGS, face->tags);
+ if (rc >= MAXSZ_POLICY_TAGS)
+ WARN("[hc_face_snprintf] Unexpected truncation of policy tags string");
+ if (rc < 0) return rc;
+
+ return snprintf(
+ s, size, "[#%d %s] %s %s %s %s %s/%s [%d] (%s)", face->id, face->name,
+ face->netdevice.index != NETDEVICE_UNDEFINED_INDEX ? face->netdevice.name
+ : "*",
+ face_type_str(face->type), local, remote, face_state_str(face->state),
+ face_state_str(face->admin_state), face->priority, tags);
+}
+
+int _hc_face_snprintf(char *s, size_t size, const hc_object_t *object) {
+ return hc_face_snprintf(s, size, &object->face);
+}
+
+int hc_face_create(hc_sock_t *s, hc_face_t *face) {
+ hc_object_t object;
+ memset(&object, 0, sizeof(hc_object_t));
+ object.face = *face;
+ return hc_execute(s, ACTION_CREATE, OBJECT_TYPE_FACE, &object, NULL);
+}
+
+int hc_face_get(hc_sock_t *s, hc_face_t *face, hc_data_t **pdata) {
+ hc_object_t object;
+ memset(&object, 0, sizeof(hc_object_t));
+ object.face = *face;
+ return hc_execute(s, ACTION_GET, OBJECT_TYPE_FACE, &object, pdata);
+}
+
+int hc_face_delete(hc_sock_t *s, hc_face_t *face) {
+ hc_object_t object;
+ memset(&object, 0, sizeof(hc_object_t));
+ object.face = *face;
+ return hc_execute(s, ACTION_DELETE, OBJECT_TYPE_FACE, &object, NULL);
+}
+
+int hc_face_list(hc_sock_t *s, hc_data_t **pdata) {
+ return hc_execute(s, ACTION_LIST, OBJECT_TYPE_FACE, NULL, pdata);
+}
+
+int hc_face_list_async(hc_sock_t *s) {
+ return hc_execute_async(s, ACTION_LIST, OBJECT_TYPE_FACE, NULL, NULL, NULL);
+}
+
+GENERATE_FIND(face);
+
+DECLARE_OBJECT_OPS(OBJECT_TYPE_FACE, face);
diff --git a/ctrl/libhicnctrl/src/objects/face.h b/ctrl/libhicnctrl/src/objects/face.h
new file mode 100644
index 000000000..08f90f195
--- /dev/null
+++ b/ctrl/libhicnctrl/src/objects/face.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2021-2022 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 face.h
+ * \brief Face.
+ */
+
+#ifndef HICNCTRL_IMPL_OBJECTS_FACE_H
+#define HICNCTRL_IMPL_OBJECTS_FACE_H
+
+#include "../object_vft.h"
+
+int hc_face_validate(const hc_face_t *face, bool allow_partial);
+
+DECLARE_OBJECT_OPS_H(OBJECT_TYPE_FACE, face);
+
+#endif /* HICNCTRL_IMPL_OBJECTS_FACE_H */
diff --git a/ctrl/libhicnctrl/src/objects/listener.c b/ctrl/libhicnctrl/src/objects/listener.c
new file mode 100644
index 000000000..660a4931d
--- /dev/null
+++ b/ctrl/libhicnctrl/src/objects/listener.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2021-2022 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 listener.c
+ * \brief Implementation of listener.
+ */
+
+#include <string.h>
+
+#include <hicn/ctrl/api.h>
+#include <hicn/ctrl/object.h>
+#include <hicn/ctrl/objects/listener.h>
+#include <hicn/util/log.h>
+
+#include "../object_vft.h"
+#include "../object_private.h"
+#include "base.h"
+
+bool hc_listener_is_local(const hc_listener_t *listener) {
+ return (strncmp(listener->interface_name, "lo", INTERFACE_LEN) == 0);
+}
+
+/* LISTENER VALIDATE */
+
+int hc_listener_validate(const hc_listener_t *listener, bool allow_partial) {
+ // if a field is specified it should be valid
+ // then we allow different specification, by key or by attributes, if
+ // allow_partial
+
+ int has_id = 0;
+ int has_name = 0;
+ int has_interface_name = 0;
+ int has_type = 0;
+ int has_family = 0;
+ int has_local_addr = 0;
+ int has_local_port = 0;
+
+ if (listener->id == ~0) {
+ ERROR("[hc_listener_validate] Invalid id specified");
+ return -1;
+ }
+ has_id = 1;
+
+ if (!isempty(listener->name)) {
+ if (!IS_VALID_NAME(listener->name)) {
+ ERROR("[hc_listener_validate] Invalid name specified");
+ return -1;
+ }
+ has_name = 1;
+ }
+
+ if (!isempty(listener->interface_name)) {
+ if (!IS_VALID_INTERFACE_NAME(listener->interface_name)) {
+ ERROR("[hc_listener_validate] Invalid interface_name specified");
+ return -1;
+ }
+ has_interface_name = 1;
+ }
+
+ if (listener->type != FACE_TYPE_UNDEFINED) {
+ if (!IS_VALID_TYPE(listener->type)) {
+ ERROR("[hc_listener_validate] Invalid type specified");
+ return -1;
+ }
+ has_type = 1;
+ }
+
+ if (listener->family != AF_UNSPEC) {
+ if (!IS_VALID_FAMILY(listener->family)) {
+ ERROR("[hc_listener_validat] Invalid family specified");
+ return -1;
+ }
+ has_family = 1;
+ }
+
+ if (!hicn_ip_address_empty(&listener->local_addr)) {
+ if (!IS_VALID_ADDRESS(listener->local_addr)) {
+ ERROR("[hc_listener_validate] Invalid local_addr specified");
+ return -1;
+ }
+ has_local_addr = 1;
+ }
+
+ if (listener->local_port != 0) {
+ if (!IS_VALID_PORT(listener->local_port)) {
+ ERROR("[hc_listener_validate] Invalid local_port specified");
+ return -1;
+ }
+ has_local_port = 1;
+ }
+
+ if (allow_partial) {
+ if ((has_id || has_name) && !has_type && !has_family && !has_local_port &&
+ !has_local_port)
+ return 0;
+ else if (has_name && has_type && has_family && has_local_addr &&
+ has_local_port)
+ return 0;
+ else
+ return -1;
+ } else {
+ /* name is optional */
+ if (has_id && has_interface_name && has_type && has_family &&
+ has_local_addr && has_local_port)
+ return 0;
+ return -1;
+ }
+}
+
+int _hc_listener_validate(const hc_object_t *object, bool allow_partial) {
+ return hc_listener_validate(&object->listener, allow_partial);
+}
+
+/* LISTENER CMP */
+
+int hc_listener_cmp(const hc_listener_t *l1, const hc_listener_t *l2) {
+ int rc;
+
+ rc = INT_CMP(l1->type, l2->type);
+ if (rc != 0) return rc;
+
+ rc = INT_CMP(l1->family, l2->family);
+ if (rc != 0) return rc;
+
+ rc = strncmp(l1->interface_name, l2->interface_name, INTERFACE_LEN);
+ if (rc != 0) return rc;
+
+ rc = hicn_ip_address_cmp(&l1->local_addr, &l2->local_addr);
+ if (rc != 0) return rc;
+
+ rc = INT_CMP(l1->local_port, l2->local_port);
+ if (rc != 0) return rc;
+
+ return rc;
+}
+
+int _hc_listener_cmp(const hc_object_t *object1, const hc_object_t *object2) {
+ return hc_listener_cmp(&object1->listener, &object2->listener);
+}
+
+/* LISTENER SNPRINTF */
+
+/* /!\ Please update constants in header file upon changes */
+int hc_listener_snprintf(char *s, size_t size, const hc_listener_t *listener) {
+ char local[MAXSZ_URL];
+ int rc;
+ rc = url_snprintf(local, MAXSZ_URL, &listener->local_addr,
+ listener->local_port);
+ if (rc >= MAXSZ_URL)
+ WARN("[hc_listener_snprintf] Unexpected truncation of URL string");
+ if (rc < 0) return rc;
+
+ return snprintf(s, size, "%s %s %s interface=%s", listener->name, local,
+ face_type_str(listener->type), listener->interface_name);
+}
+
+int _hc_listener_snprintf(char *s, size_t size, const hc_object_t *object) {
+ return hc_listener_snprintf(s, size, &object->listener);
+}
+
+/* OPERATIONS */
+
+int hc_listener_create(hc_sock_t *s, hc_listener_t *listener) {
+ hc_object_t object;
+ memset(&object, 0, sizeof(hc_object_t));
+ object.listener = *listener;
+ return hc_execute(s, ACTION_CREATE, OBJECT_TYPE_LISTENER, &object, NULL);
+}
+
+int hc_listener_get(hc_sock_t *s, hc_listener_t *listener, hc_data_t **pdata) {
+ hc_object_t object;
+ memset(&object, 0, sizeof(hc_object_t));
+ object.listener = *listener;
+ return hc_execute(s, ACTION_GET, OBJECT_TYPE_LISTENER, &object, pdata);
+}
+
+int hc_listener_delete(hc_sock_t *s, hc_listener_t *listener) {
+ hc_object_t object;
+ memset(&object, 0, sizeof(hc_object_t));
+ object.listener = *listener;
+ return hc_execute(s, ACTION_DELETE, OBJECT_TYPE_LISTENER, &object, NULL);
+}
+
+int hc_listener_list(hc_sock_t *s, hc_data_t **pdata) {
+ return hc_execute(s, ACTION_LIST, OBJECT_TYPE_LISTENER, NULL, pdata);
+}
+
+GENERATE_FIND(listener);
+
+DECLARE_OBJECT_OPS(OBJECT_TYPE_LISTENER, listener);
diff --git a/ctrl/libhicnctrl/src/objects/listener.h b/ctrl/libhicnctrl/src/objects/listener.h
new file mode 100644
index 000000000..515c8f0ad
--- /dev/null
+++ b/ctrl/libhicnctrl/src/objects/listener.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2021-2022 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 listener.h
+ * \brief Listener.
+ */
+
+#ifndef HICNCTRL_IMPL_OBJECTS_LISTENER_H
+#define HICNCTRL_IMPL_OBJECTS_LISTENER_H
+
+#include "../object_vft.h"
+
+bool hc_listener_is_local(const hc_listener_t *listener);
+
+DECLARE_OBJECT_OPS_H(OBJECT_TYPE_LISTENER, listener);
+
+#endif /* HICNCTRL_IMPL_OBJECTS_LISTENER_H */
diff --git a/ctrl/libhicnctrl/src/objects/route.c b/ctrl/libhicnctrl/src/objects/route.c
new file mode 100644
index 000000000..44f39bcd7
--- /dev/null
+++ b/ctrl/libhicnctrl/src/objects/route.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2021-2022 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 route.c
+ * \brief Implementation of route object.
+ */
+
+#include <hicn/ctrl/api.h>
+#include <hicn/ctrl/object.h>
+#include <hicn/ctrl/objects/route.h>
+#include <hicn/util/log.h>
+
+#include "../object_private.h"
+#include "../object_vft.h"
+#include "face.h"
+#include "base.h"
+
+bool hc_route_has_face(const hc_route_t *route) {
+ return !iszero(&route->face, sizeof(hc_face_t));
+}
+
+/* ROUTE VALIDATE */
+
+int hc_route_validate(const hc_route_t *route, bool allow_partial) {
+ int has_id = 0;
+ int has_name = 0;
+ int has_face = 0;
+
+ 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;
+ }
+ has_id = 1;
+
+ if (!isempty(route->face_name)) {
+ if (!IS_VALID_NAME(route->face_name)) {
+ ERROR("[hc_route_validate] Invalid name specified");
+ return -1;
+ }
+ has_name = 1;
+ }
+
+ if (route->family != AF_UNSPEC) {
+ if (!IS_VALID_FAMILY(route->family)) {
+ ERROR("[hc_route_validate] Invalid family specified");
+ return -1;
+ }
+ has_family = 1;
+ }
+
+ if (!hicn_ip_address_empty(&route->remote_addr)) {
+ if (!IS_VALID_ADDRESS(route->remote_addr)) {
+ ERROR("[hc_route_validate] Invalid remote_addr specified");
+ return -1;
+ }
+ has_remote_addr = 1;
+ }
+
+ if (!IS_VALID_ROUTE_COST(route->cost)) {
+ ERROR("[hc_route_validate] Invalid cost");
+ return -1;
+ }
+
+ if (!IS_VALID_PREFIX_LEN(route->len)) {
+ ERROR("[hc_route_validate] Invalid len");
+ return -1;
+ }
+
+ if (hc_route_has_face(route)) {
+ if (!hc_face_validate(&route->face, allow_partial)) {
+ ERROR("[hc_route_validate] Invalid face");
+ return -1;
+ }
+ 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;
+
+ return -1;
+}
+
+int _hc_route_validate(const hc_object_t *object, bool allow_partial) {
+ return hc_route_validate(&object->route, allow_partial);
+}
+
+/* ROUTE CMP */
+
+// XXX TODO
+int hc_route_cmp(const hc_route_t *route1, const hc_route_t *route2) {
+ return -1;
+}
+
+int _hc_route_cmp(const hc_object_t *object1, const hc_object_t *object2) {
+ return hc_route_cmp(&object1->route, &object2->route);
+}
+
+/* ROUTE SNPRINTF */
+
+/* /!\ Please update constants in header file upon changes */
+int hc_route_snprintf(char *s, size_t size, const hc_route_t *route) {
+ /* interface cost prefix length */
+
+ char prefix[MAXSZ_IP_ADDRESS];
+ int rc;
+
+ rc = hicn_ip_address_snprintf(prefix, MAXSZ_IP_ADDRESS, &route->remote_addr);
+ if (rc >= MAXSZ_IP_ADDRESS)
+ ;
+ if (rc < 0) return rc;
+
+ return snprintf(s, size, "%d (%s) %*d %s %*d", route->face_id,
+ route->face_name, MAXSZ_COST, route->cost, prefix, MAXSZ_LEN,
+ route->len);
+}
+
+int _hc_route_snprintf(char *s, size_t size, const hc_object_t *object) {
+ return hc_route_snprintf(s, size, &object->route);
+}
+
+int hc_route_create(hc_sock_t *s, hc_route_t *route) {
+ hc_object_t object;
+ memset(&object, 0, sizeof(hc_object_t));
+ object.route = *route;
+ return hc_execute(s, ACTION_CREATE, OBJECT_TYPE_ROUTE, &object, NULL);
+}
+
+int hc_route_get(hc_sock_t *s, hc_route_t *route, hc_data_t **pdata) {
+ hc_object_t object;
+ memset(&object, 0, sizeof(hc_object_t));
+ object.route = *route;
+ return hc_execute(s, ACTION_GET, OBJECT_TYPE_ROUTE, &object, pdata);
+}
+
+int hc_route_delete(hc_sock_t *s, hc_route_t *route) {
+ hc_object_t object;
+ memset(&object, 0, sizeof(hc_object_t));
+ object.route = *route;
+ return hc_execute(s, ACTION_DELETE, OBJECT_TYPE_ROUTE, &object, NULL);
+}
+
+int hc_route_list(hc_sock_t *s, hc_data_t **pdata) {
+ return hc_execute(s, ACTION_LIST, OBJECT_TYPE_ROUTE, NULL, pdata);
+}
+
+int hc_route_list_async(hc_sock_t *s) {
+ return hc_execute_async(s, ACTION_LIST, OBJECT_TYPE_ROUTE, NULL, NULL, NULL);
+}
+
+// XXX difference between GET and FIND
+GENERATE_FIND(route);
+
+DECLARE_OBJECT_OPS(OBJECT_TYPE_ROUTE, route);
diff --git a/ctrl/libhicnctrl/src/objects/route.h b/ctrl/libhicnctrl/src/objects/route.h
new file mode 100644
index 000000000..854bd70a6
--- /dev/null
+++ b/ctrl/libhicnctrl/src/objects/route.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2021-2022 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 route.h
+ * \brief Route.
+ */
+
+#ifndef HICNCTRL_IMPL_OBJECTS_ROUTE_H
+#define HICNCTRL_IMPL_OBJECTS_ROUTE_H
+
+#include "../object_vft.h"
+
+bool hc_route_has_face(const hc_route_t* route);
+
+DECLARE_OBJECT_OPS_H(OBJECT_TYPE_ROUTE, route);
+
+#endif /* HICNCTRL_IMPL_OBJECTS_ROUTE_H */
diff --git a/ctrl/libhicnctrl/src/objects/stats.c b/ctrl/libhicnctrl/src/objects/stats.c
new file mode 100644
index 000000000..2c3135d3c
--- /dev/null
+++ b/ctrl/libhicnctrl/src/objects/stats.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2021-2022 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 stats.c
+ * \brief Implementation of stats.
+ */
+
+#include <string.h>
+
+#include <hicn/ctrl/api.h>
+#include <hicn/ctrl/object.h>
+#include <hicn/ctrl/objects/stats.h>
+#include <hicn/util/log.h>
+
+#include "../object_vft.h"
+#include "../object_private.h"
+
+int hc_stats_snprintf(char *s, size_t size, const hc_stats_t *stats) {
+#if 0
+ INFO("Connection #%d:", conn_stats->id);
+ INFO("\tinterests received: %d pkts (%d bytes)",
+ conn_stats->stats.interests.rx_pkts,
+ conn_stats->stats.interests.rx_bytes);
+ INFO("\tinterests transmitted: %d pkts (%d bytes)",
+ conn_stats->stats.interests.tx_pkts,
+ conn_stats->stats.interests.tx_bytes);
+ INFO("\tdata received: %d pkts (%d bytes)",
+ conn_stats->stats.data.rx_pkts,
+ conn_stats->stats.data.rx_bytes);
+ INFO("\tdata transmitted: %d pkts (%d bytes)",
+ conn_stats->stats.data.tx_pkts,
+ conn_stats->stats.data.tx_bytes);
+#endif
+ return 0;
+}
+
+int hc_stats_get(hc_sock_t *s, hc_data_t **pdata) {
+ hc_object_t object;
+ memset(&object, 0, sizeof(hc_object_t));
+ object.listener = *listener;
+ return hc_execute(s, ACTION_GET, OBJECT_TYPE_STATS, &object, pdata);
+}
+
+int hc_stats_list(hc_sock_t *s, hc_data_t **pdata) {
+ return hc_execute(s, ACTION_LIST, OBJECT_TYPE_STATS, NULL, pdata);
+}
diff --git a/ctrl/libhicnctrl/src/objects/strategy.c b/ctrl/libhicnctrl/src/objects/strategy.c
new file mode 100644
index 000000000..0e7a5787e
--- /dev/null
+++ b/ctrl/libhicnctrl/src/objects/strategy.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2021-2022 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 strategy.c
+ * \brief Implementation of strategy.
+ */
+
+#include <hicn/ctrl/api.h>
+#include <hicn/ctrl/object.h>
+#include <hicn/ctrl/objects/strategy.h>
+#include <hicn/util/log.h>
+
+#include "../object_vft.h"
+#include "../object_private.h"
+
+/* STREATEGY VALIDATE */
+
+int hc_strategy_validate(const hc_strategy_t *strategy, bool allow_partial) {
+ // TODO verify name
+ return 0;
+}
+
+int _hc_strategy_validate(const hc_object_t *object, bool allow_partial) {
+ return hc_strategy_validate(&object->strategy, allow_partial);
+}
+
+/* STRATEGY CMP */
+
+int hc_strategy_cmp(const hc_strategy_t *s1, const hc_strategy_t *s2) {
+ return strcmp(s1->name, s2->name);
+}
+
+int _hc_strategy_cmp(const hc_object_t *object1, const hc_object_t *object2) {
+ return hc_strategy_cmp(&object1->strategy, &object2->strategy);
+}
+
+/* STRATEGY SNPRINTF */
+
+/* /!\ Please update constants in header file upon changes */
+int hc_strategy_snprintf(char *s, size_t size, const hc_strategy_t *strategy) {
+ return snprintf(s, size, "%s", strategy->name);
+}
+
+int _hc_strategy_snprintf(char *s, size_t size, const hc_object_t *object) {
+ return hc_strategy_snprintf(s, size, &object->strategy);
+}
+
+/* OPERATIONS */
+
+int hc_strategy_create(hc_sock_t *s, hc_strategy_t *strategy) { return -1; }
+
+int hc_strategy_get(hc_sock_t *s, hc_strategy_t *strategy, hc_data_t **pdata) {
+ return -1;
+}
+
+int hc_strategy_delete(hc_sock_t *s, hc_strategy_t *strategy) { return -1; }
+
+int hc_strategy_list(hc_sock_t *s, hc_data_t **pdata) {
+ return hc_execute(s, ACTION_LIST, OBJECT_TYPE_STRATEGY, NULL, pdata);
+}
+
+/* new api */
+
+int hc_strategy_set(hc_sock_t *s, hc_strategy_t *strategy) {
+ hc_object_t object;
+ memset(&object, 0, sizeof(hc_object_t));
+ object.strategy = *strategy;
+ return hc_execute(s, ACTION_SET, OBJECT_TYPE_STRATEGY, &object, NULL);
+}
+
+#if 0
+int hc_strategy_add_local_prefix(hc_sock_t *s, hc_strategy_t *strategy) {
+ return s->hc_strategy_add_local_prefix(s, strategy);
+}
+#endif
+
+GENERATE_FIND(strategy);
+
+DECLARE_OBJECT_OPS(OBJECT_TYPE_STRATEGY, strategy);
diff --git a/ctrl/libhicnctrl/src/objects/strategy.h b/ctrl/libhicnctrl/src/objects/strategy.h
new file mode 100644
index 000000000..0cc4f525d
--- /dev/null
+++ b/ctrl/libhicnctrl/src/objects/strategy.h
@@ -0,0 +1,29 @@
+
+/*
+ * Copyright (c) 2021-2022 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 listener.h
+ * \brief Listener.
+ */
+
+#ifndef HICNCTRL_IMPL_OBJECTS_STRATEGY_H
+#define HICNCTRL_IMPL_OBJECTS_STRATEGY_H
+
+#include "../object_vft.h"
+
+DECLARE_OBJECT_OPS_H(OBJECT_TYPE_STRATEGY, strategy);
+
+#endif /* HICNCTRL_IMPL_OBJECTS_STRATEGY_H */
diff --git a/ctrl/libhicnctrl/src/objects/subscription.c b/ctrl/libhicnctrl/src/objects/subscription.c
new file mode 100644
index 000000000..087e42ffb
--- /dev/null
+++ b/ctrl/libhicnctrl/src/objects/subscription.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2021-2022 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 subscription.c
+ * \brief Implementation of subscription.
+ */
+
+#include <hicn/ctrl/api.h>
+#include <hicn/ctrl/object.h>
+#include <hicn/ctrl/objects/subscription.h>
+#include <hicn/util/log.h>
+
+#include "../object_vft.h"
+#include "../object_private.h"
+
+/* SUBSCRIPTION VALIDATE */
+
+int hc_subscription_validate(const hc_subscription_t *subscription,
+ bool allow_partial) {
+ /* Any topic is considered valid */
+ return 0;
+}
+
+int _hc_subscription_validate(const hc_object_t *object, bool allow_partial) {
+ return hc_subscription_validate(&object->subscription, allow_partial);
+}
+
+/* LISTENER CMP */
+
+int hc_subscription_cmp(const hc_subscription_t *l1,
+ const hc_subscription_t *l2) {
+ return -1;
+}
+
+int _hc_subscription_cmp(const hc_object_t *object1,
+ const hc_object_t *object2) {
+ return hc_subscription_cmp(&object1->subscription, &object2->subscription);
+}
+
+/* SUBSCRIPTION SNPRINTF */
+
+/* /!\ Please update constants in header file upon changes */
+int hc_subscription_snprintf(char *s, size_t size,
+ const hc_subscription_t *subscription) {
+ return -1;
+}
+
+int _hc_subscription_snprintf(char *s, size_t size, const hc_object_t *object) {
+ return hc_subscription_snprintf(s, size, &object->subscription);
+}
+
+/* OPERATIONS */
+
+int hc_subscription_create(hc_sock_t *s, hc_subscription_t *subscription) {
+ hc_object_t object;
+ memset(&object, 0, sizeof(hc_object_t));
+ object.subscription = *subscription;
+ return hc_execute(s, ACTION_CREATE, OBJECT_TYPE_SUBSCRIPTION, &object, NULL);
+}
+
+int hc_subscription_get(hc_sock_t *s, hc_subscription_t *subscription,
+ hc_data_t **pdata) {
+ hc_object_t object;
+ memset(&object, 0, sizeof(hc_object_t));
+ object.subscription = *subscription;
+ return hc_execute(s, ACTION_GET, OBJECT_TYPE_SUBSCRIPTION, &object, pdata);
+}
+
+int hc_subscription_delete(hc_sock_t *s, hc_subscription_t *subscription) {
+ hc_object_t object;
+ memset(&object, 0, sizeof(hc_object_t));
+ object.subscription = *subscription;
+ return hc_execute(s, ACTION_DELETE, OBJECT_TYPE_SUBSCRIPTION, &object, NULL);
+}
+
+int hc_subscription_list(hc_sock_t *s, hc_data_t **pdata) {
+ return hc_execute(s, ACTION_LIST, OBJECT_TYPE_SUBSCRIPTION, NULL, pdata);
+}
+
+GENERATE_FIND(subscription);
+DECLARE_OBJECT_OPS(OBJECT_TYPE_SUBSCRIPTION, subscription);
diff --git a/ctrl/libhicnctrl/src/objects/subscription.h b/ctrl/libhicnctrl/src/objects/subscription.h
new file mode 100644
index 000000000..6eb7583c6
--- /dev/null
+++ b/ctrl/libhicnctrl/src/objects/subscription.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2021-2022 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 subscription.h
+ * \brief Listener.
+ */
+
+#ifndef HICNCTRL_IMPL_OBJECTS_SUBSCRIPTION_H
+#define HICNCTRL_IMPL_OBJECTS_SUBSCRIPTION_H
+
+#include "../object_vft.h"
+
+DECLARE_OBJECT_OPS_H(OBJECT_TYPE_SUBSCRIPTION, subscription);
+
+#endif /* HICNCTRL_IMPL_OBJECTS_SUBSCRIPTION_H */