aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/includes/CMakeLists.txt1
-rw-r--r--lib/includes/hicn/base.h9
-rw-r--r--lib/includes/hicn/face.h213
-rw-r--r--lib/includes/hicn/policy.h64
-rw-r--r--lib/includes/hicn/protocol/tcp.h6
-rw-r--r--lib/includes/hicn/util/ip_address.h2
-rw-r--r--lib/src/CMakeLists.txt6
-rw-r--r--lib/src/face.c422
-rw-r--r--lib/src/util/ip_address.c11
9 files changed, 658 insertions, 76 deletions
diff --git a/lib/includes/CMakeLists.txt b/lib/includes/CMakeLists.txt
index 12529bd57..6184f4708 100644
--- a/lib/includes/CMakeLists.txt
+++ b/lib/includes/CMakeLists.txt
@@ -23,6 +23,7 @@ set(LIBHICN_HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/hicn/common.h
${CMAKE_CURRENT_SOURCE_DIR}/hicn/compat.h
${CMAKE_CURRENT_SOURCE_DIR}/hicn/error.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/hicn/face.h
${CMAKE_CURRENT_SOURCE_DIR}/hicn/header.h
${CMAKE_CURRENT_SOURCE_DIR}/hicn/mapme.h
${CMAKE_CURRENT_SOURCE_DIR}/hicn/name.h
diff --git a/lib/includes/hicn/base.h b/lib/includes/hicn/base.h
index d8a79a9c2..3112d1140 100644
--- a/lib/includes/hicn/base.h
+++ b/lib/includes/hicn/base.h
@@ -27,7 +27,7 @@
#define HICN_DEFAULT_TTL 254
typedef u32 hicn_faceid_t;
-typedef u8 hicn_pathlabel_t;
+typedef u32 hicn_pathlabel_t;
typedef u32 hicn_lifetime_t;
#define HICN_MAX_LIFETIME_SCALED 0xFFFF
@@ -95,12 +95,16 @@ HICN_TYPE(int x, int y, int z, int t)
#endif
#define HICN_TYPE_IPV4_TCP HICN_TYPE(IPPROTO_IP, IPPROTO_TCP, IPPROTO_NONE, IPPROTO_NONE)
+#define HICN_TYPE_IPV4_UDP HICN_TYPE(IPPROTO_IP, IPPROTO_UDP, IPPROTO_NONE, IPPROTO_NONE)
#define HICN_TYPE_IPV4_ICMP HICN_TYPE(IPPROTO_IP, IPPROTO_ICMP, IPPROTO_NONE, IPPROTO_NONE)
#define HICN_TYPE_IPV6_TCP HICN_TYPE(IPPROTO_IPV6, IPPROTO_TCP, IPPROTO_NONE, IPPROTO_NONE)
+#define HICN_TYPE_IPV6_UDP HICN_TYPE(IPPROTO_IPV6, IPPROTO_UDP, IPPROTO_NONE, IPPROTO_NONE)
#define HICN_TYPE_IPV6_ICMP HICN_TYPE(IPPROTO_IPV6, IPPROTO_ICMPV6, IPPROTO_NONE, IPPROTO_NONE)
#define HICN_TYPE_IPV4_TCP_AH HICN_TYPE(IPPROTO_IP, IPPROTO_TCP, IPPROTO_NONE, IPPROTO_NONE)
+#define HICN_TYPE_IPV4_UDP_AH HICN_TYPE(IPPROTO_IP, IPPROTO_UDP, IPPROTO_NONE, IPPROTO_NONE)
#define HICN_TYPE_IPV4_ICMP_AH HICN_TYPE(IPPROTO_IP, IPPROTO_ICMP, IPPROTO_NONE, IPPROTO_NONE)
#define HICN_TYPE_IPV6_TCP_AH HICN_TYPE(IPPROTO_IPV6, IPPROTO_TCP, IPPROTO_AH, IPPROTO_NONE)
+#define HICN_TYPE_IPV6_UDP_AH HICN_TYPE(IPPROTO_IPV6, IPPROTO_UDP, IPPROTO_AH, IPPROTO_NONE)
#define HICN_TYPE_IPV6_ICMP_AH HICN_TYPE(IPPROTO_IPV6, IPPROTO_ICMPV6, IPPROTO_AH, IPPROTO_NONE)
#define HICN_TYPE_NONE HICN_TYPE(IPPROTO_NONE, IPPROTO_NONE, IPPROTO_NONE, IPPROTO_NONE)
@@ -127,8 +131,9 @@ typedef enum
* NOTE: this computation is not (yet) part of the hICN specification.
*/
+// XXX TODO deprecate TODO XXX
#define HICN_PATH_LABEL_MASK 0xF000 /* 1000 0000 0000 0000 */
-#define HICN_PATH_LABEL_SIZE 8
+#define HICN_PATH_LABEL_SIZE 8 /* XXX in bits ? */
/**
* @brief Path label update
diff --git a/lib/includes/hicn/face.h b/lib/includes/hicn/face.h
new file mode 100644
index 000000000..45a1b97da
--- /dev/null
+++ b/lib/includes/hicn/face.h
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * \file face.h
+ * \brief Face abstraction
+ */
+#ifndef HICN_FACE_H
+#define HICN_FACE_H
+
+#ifndef SPACES
+#define SPACES(x) x
+#endif
+#ifndef SPACE
+#define SPACE 1
+#endif
+#ifndef NULLTERM
+#define NULLTERM 1
+#endif
+
+#include <hicn/policy.h>
+
+#include <hicn/util/ip_address.h>
+
+/* Netdevice type */
+
+#include <net/if.h> // IFNAMSIZ
+
+#define foreach_netdevice_type \
+ _(UNDEFINED) \
+ _(LOOPBACK) \
+ _(WIRED) \
+ _(WIFI) \
+ _(CELLULAR) \
+ _(VPN) \
+ _(N)
+
+#define MAXSZ_NETDEVICE_TYPE_ 9
+#define MAXSZ_NETDEVICE_TYPE MAXSZ_NETDEVICE_TYPE_ + NULLTERM
+
+typedef enum {
+#define _(x) NETDEVICE_TYPE_ ## x,
+foreach_netdevice_type
+#undef _
+} netdevice_type_t;
+
+extern const char * _netdevice_type_str[];
+#define netdevice_type_str(x) _netdevice_type_str[x]
+
+
+/* Netdevice */
+
+/**
+ * \brief Netdevice type
+ *
+ * NOTE
+ * - This struct cannot be made opaque as it is currently part of face_t
+ * - We recommand using the API as to keep redundant attributes consistent
+ */
+typedef struct {
+ u32 index;
+ char name[IFNAMSIZ];
+} netdevice_t;
+
+#define NETDEVICE_EMPTY (netdevice_t) { \
+ .index = 0, \
+ .name = {0}, \
+}
+
+netdevice_t * netdevice_create_from_index(u32 index);
+netdevice_t * netdevice_create_from_name(const char * name);
+#define netdevice_initialize_from_index netdevice_set_index
+#define netdevice_initialize_from_name netdevice_set_name
+void netdevice_free(netdevice_t * netdevice);
+int netdevice_get_index(const netdevice_t * netdevice, u32 * index);
+int netdevice_set_index(netdevice_t * netdevice, u32 index);
+int netdevice_get_name(const netdevice_t * netdevice, const char ** name);
+int netdevice_set_name(netdevice_t * netdevice, const char * name);
+int netdevice_update_index(netdevice_t * netdevice);
+int netdevice_update_name(netdevice_t * netdevice);
+int netdevice_cmp(const netdevice_t * nd1, const netdevice_t * nd2);
+
+#define NETDEVICE_UNDEFINED_INDEX 0
+
+/* Face state */
+
+#define foreach_face_state \
+ _(UNDEFINED) \
+ _(DOWN) \
+ _(UP) \
+ _(N)
+
+
+#define MAXSZ_FACE_STATE_ 9
+#define MAXSZ_FACE_STATE MAXSZ_FACE_STATE_ + 1
+
+typedef enum {
+#define _(x) FACE_STATE_ ## x,
+foreach_face_state
+#undef _
+} face_state_t;
+
+extern const char * _face_state_str[];
+
+#define face_state_str(x) _face_state_str[x]
+
+
+/* Face type */
+
+#define foreach_face_type \
+ _(UNDEFINED) \
+ _(HICN) \
+ _(HICN_LISTENER) \
+ _(TCP) \
+ _(TCP_LISTENER) \
+ _(UDP) \
+ _(UDP_LISTENER) \
+ _(N)
+
+#define MAXSZ_FACE_TYPE_ 13
+#define MAXSZ_FACE_TYPE MAXSZ_FACE_TYPE_ + 1
+
+typedef enum {
+#define _(x) FACE_TYPE_ ## x,
+foreach_face_type
+#undef _
+} face_type_t;
+
+#define face_type_is_valid(face_type) \
+ (((face_type) >= FACE_TYPE_UNDEFINED) && (face_type < FACE_TYPE_N))
+#define face_type_is_defined(face_type) \
+ (((face_type) > FACE_TYPE_UNDEFINED) && (face_type < FACE_TYPE_N))
+
+extern const char * _face_type_str[];
+#define face_type_str(x) _face_type_str[x]
+
+
+#ifdef WITH_POLICY
+#define MAXSZ_FACE_ MAXSZ_FACE_TYPE_ + 2 * MAXSZ_URL_ + 2 * MAXSZ_FACE_STATE_ + MAXSZ_POLICY_TAGS_ + 7
+#else
+#define MAXSZ_FACE_ MAXSZ_FACE_TYPE_ + 2 * MAXSZ_URL_ + 2 * MAXSZ_FACE_STATE_ + 4
+#endif /* WITH_POLICY */
+#define MAXSZ_FACE MAXSZ_FACE_ + 1
+
+/* Face */
+
+typedef u32 face_id_t;
+
+typedef struct {
+ face_type_t type;
+ face_state_t admin_state;
+ face_state_t state;
+#ifdef WITH_POLICY
+ uint32_t priority;
+ policy_tags_t tags; /**< \see policy_tag_t */
+#endif /* WITH_POLICY */
+
+ /*
+ * Depending on the face type, some of the following fields will be unused
+ */
+ netdevice_t netdevice;
+ int family; /* To access family independently of face type */
+ ip_address_t local_addr;
+ ip_address_t remote_addr;
+ u16 local_port;
+ u16 remote_port;
+} face_t;
+
+int face_initialize(face_t * face);
+int face_initialize_udp(face_t * face, const char * interface_name,
+ const ip_address_t * local_addr, u16 local_port,
+ const ip_address_t * remote_addr, u16 remote_port,
+ int family);
+int face_initialize_udp_sa(face_t * face,
+ const char * interface_name,
+ const struct sockaddr * local_addr, const struct sockaddr * remote_addr);
+
+face_t * face_create();
+face_t * face_create_udp(const char * interface_name,
+ const ip_address_t * local_addr, u16 local_port,
+ const ip_address_t * remote_addr, u16 remote_port, int family);
+face_t * face_create_udp_sa(const char * interface_name,
+ const struct sockaddr * local_addr,
+ const struct sockaddr * remote_addr);
+
+int face_finalize(face_t * face);
+
+void face_free(face_t * face);
+
+typedef int (*face_cmp_t)(const face_t * f1, const face_t * f2);
+
+int face_cmp(const face_t * f1, const face_t * f2);
+
+size_t
+face_snprintf(char * s, size_t size, const face_t * face);
+
+policy_tags_t face_get_tags(const face_t * face);
+int face_set_tags(face_t * face, policy_tags_t tags);
+
+#endif /* HICN_FACE_H */
+
diff --git a/lib/includes/hicn/policy.h b/lib/includes/hicn/policy.h
index 51bab4241..1fe0dd766 100644
--- a/lib/includes/hicn/policy.h
+++ b/lib/includes/hicn/policy.h
@@ -147,68 +147,6 @@ typedef struct {
int policy_tag_state_snprintf(char * s, size_t size, const policy_tag_state_t * tag_state);
-
-/* INTERFACE STATS */
-
-typedef struct {
- float throughput;
- float latency;
- float loss_rate;
-} interface_stats_t;
-
-#define INTERFACE_STATS_NONE { \
- .throughput = 0, \
- .latency = 0, \
- .loss_rate = 0, \
-}
-
-
-/* POLICY STATS */
-
-typedef struct {
- interface_stats_t wired;
- interface_stats_t wifi;
- interface_stats_t cellular;
- interface_stats_t all;
-} policy_stats_t;
-
-#define POLICY_STATS_NONE { \
- .wired = INTERFACE_STATS_NONE, \
- .wifi = INTERFACE_STATS_NONE, \
- .cellular = INTERFACE_STATS_NONE, \
- .all = INTERFACE_STATS_NONE, \
-}
-
-typedef struct {
- uint32_t num_packets;
- uint32_t num_bytes;
- uint32_t num_losses;
- uint32_t latency_idle;
-} interface_counters_t;
-
-#define INTERFACE_COUNTERS_NONE { \
- .num_packets = 0, \
- .num_bytes = 0, \
- .num_losses = 0, \
- .latency_idle = 0, \
-}
-
-typedef struct {
- interface_counters_t wired;
- interface_counters_t wifi;
- interface_counters_t cellular;
- interface_counters_t all;
- uint64_t last_update;
-} policy_counters_t;
-
-#define POLICY_COUNTERS_NONE (policy_counters_t) { \
- .wired = INTERFACE_COUNTERS_NONE, \
- .wifi = INTERFACE_COUNTERS_NONE, \
- .cellular = INTERFACE_COUNTERS_NONE, \
- .all = INTERFACE_COUNTERS_NONE, \
- .last_update = 0, \
-}
-
/* POLICY */
#define APP_NAME_LEN 128
@@ -216,7 +154,6 @@ typedef struct {
typedef struct {
char app_name[APP_NAME_LEN];
policy_tag_state_t tags[POLICY_TAG_N];
- policy_stats_t stats;
} policy_t;
static const policy_t POLICY_NONE = {
@@ -226,7 +163,6 @@ static const policy_t POLICY_NONE = {
foreach_policy_tag
#undef _
},
- .stats = POLICY_STATS_NONE,
};
diff --git a/lib/includes/hicn/protocol/tcp.h b/lib/includes/hicn/protocol/tcp.h
index ded9a06b2..5cf1a3625 100644
--- a/lib/includes/hicn/protocol/tcp.h
+++ b/lib/includes/hicn/protocol/tcp.h
@@ -42,11 +42,7 @@ typedef struct
union
{
u32 seq_ack;
- struct
- {
- hicn_pathlabel_t pathlabel;
- u8 pad[3];
- };
+ hicn_pathlabel_t pathlabel;
};
union
diff --git a/lib/includes/hicn/util/ip_address.h b/lib/includes/hicn/util/ip_address.h
index 4facd9ad0..27880047c 100644
--- a/lib/includes/hicn/util/ip_address.h
+++ b/lib/includes/hicn/util/ip_address.h
@@ -108,6 +108,7 @@ typedef struct {
#define MAXSZ_PREFIX_ MAXSZ_IP_ADDRESS_ + 1 + 3
#define MAXSZ_PREFIX MAXSZ_PREFIX_ + 1
+#define MAXSZ_IP_PREFIX MAXSZ_PREFIX
extern const ip_address_t IPV4_LOOPBACK;
extern const ip_address_t IPV6_LOOPBACK;
@@ -146,6 +147,7 @@ int ip_address_empty(const ip_address_t * ip);
int ip_prefix_pton (const char *ip_address_str, ip_prefix_t * ip_prefix);
int ip_prefix_ntop_short (const ip_prefix_t * ip_prefix, char *dst, size_t size);
int ip_prefix_ntop (const ip_prefix_t * ip_prefix, char *dst, size_t size);
+int ip_prefix_snprintf(char * s, size_t size, const ip_prefix_t * prefix);
int ip_prefix_len (const ip_prefix_t * prefix);
bool ip_prefix_empty (const ip_prefix_t * prefix);
int ip_prefix_to_sockaddr(const ip_prefix_t * prefix, struct sockaddr *sa);
diff --git a/lib/src/CMakeLists.txt b/lib/src/CMakeLists.txt
index 7eecaf775..6eb4c9554 100644
--- a/lib/src/CMakeLists.txt
+++ b/lib/src/CMakeLists.txt
@@ -17,6 +17,7 @@ list(APPEND LIBHICN_SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/common.c
${CMAKE_CURRENT_SOURCE_DIR}/compat.c
${CMAKE_CURRENT_SOURCE_DIR}/error.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/face.c
${CMAKE_CURRENT_SOURCE_DIR}/mapme.c
${CMAKE_CURRENT_SOURCE_DIR}/name.c
${CMAKE_CURRENT_SOURCE_DIR}/ops.c
@@ -30,7 +31,10 @@ list(APPEND LIBHICN_SOURCE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/util/log.c
)
-set (COMPILER_DEFINITIONS "-DWITH_MAPME")
+set (COMPILER_DEFINITIONS
+ "-DWITH_MAPME"
+ "-DWITH_POLICY"
+)
include(BuildMacros)
include(WindowsMacros)
diff --git a/lib/src/face.c b/lib/src/face.c
new file mode 100644
index 000000000..6d0d9c486
--- /dev/null
+++ b/lib/src/face.c
@@ -0,0 +1,422 @@
+/*
+ * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * \file face.c
+ * \brief Implementation of face abstraction
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <hicn/face.h>
+#include <hicn/util/token.h>
+
+#define member_size(type, member) sizeof(((type *)0)->member)
+
+
+/* Netdevice */
+
+const char * _netdevice_type_str[] = {
+#define _(x) [NETDEVICE_TYPE_ ## x] = STRINGIZE(x),
+foreach_netdevice_type
+#undef _
+};
+
+netdevice_t *
+netdevice_create_from_index(u32 index)
+{
+ netdevice_t * netdevice = malloc(sizeof(netdevice_t));
+ if (!netdevice)
+ goto ERR_MALLOC;
+
+ int rc = netdevice_set_index(netdevice, index);
+ if (rc < 0)
+ goto ERR_INIT;
+
+ return netdevice;
+
+ERR_INIT:
+ free(netdevice);
+ERR_MALLOC:
+ return NULL;
+}
+
+netdevice_t *
+netdevice_create_from_name(const char * name)
+{
+ netdevice_t * netdevice = malloc(sizeof(netdevice_t));
+ if (!netdevice)
+ goto ERR_MALLOC;
+
+ int rc = netdevice_set_name(netdevice, name);
+ if (rc < 0)
+ goto ERR_INIT;
+
+ return netdevice;
+
+ERR_INIT:
+ free(netdevice);
+ERR_MALLOC:
+ return NULL;
+}
+
+/**
+ * \brief Update the index of the netdevice based on the name
+ */
+int
+netdevice_update_index(netdevice_t * netdevice)
+{
+ netdevice->index = if_nametoindex(netdevice->name);
+ if (netdevice->index == 0)
+ return -1;
+ return 0;
+}
+
+int
+netdevice_update_name(netdevice_t * netdevice)
+{
+ if (!if_indextoname(netdevice->index, netdevice->name))
+ return -1;
+ return 0;
+}
+
+void
+netdevice_free(netdevice_t * netdevice)
+{
+ free(netdevice);
+}
+
+int
+netdevice_get_index(const netdevice_t * netdevice, u32 * index)
+{
+ if (netdevice->index == 0)
+ return -1;
+ *index = netdevice->index;
+ return 0;
+}
+
+int
+netdevice_set_index(netdevice_t * netdevice, u32 index)
+{
+ netdevice->index = index;
+ return netdevice_update_name(netdevice);
+}
+
+int
+netdevice_get_name(const netdevice_t * netdevice, const char ** name)
+{
+ if (netdevice->name[0] == '\0')
+ return -1;
+ *name = netdevice->name;
+ return 0;
+}
+
+int
+netdevice_set_name(netdevice_t * netdevice, const char * name)
+{
+ memset(netdevice->name, 0, sizeof(netdevice->name));
+ int rc = snprintf(netdevice->name, IFNAMSIZ, "%s", name);
+ if (rc < 0)
+ return -1;
+ if (rc >= IFNAMSIZ)
+ return -2; /* truncated */
+ return netdevice_update_index(netdevice);
+}
+
+int
+netdevice_cmp(const netdevice_t * nd1, const netdevice_t * nd2)
+{
+ return (nd1->index - nd2->index);
+}
+
+
+/* Face state */
+
+const char * _face_state_str[] = {
+#define _(x) [FACE_STATE_ ## x] = STRINGIZE(x),
+foreach_face_state
+#undef _
+};
+
+
+/* Face type */
+
+const char * _face_type_str[] = {
+#define _(x) [FACE_TYPE_ ## x] = STRINGIZE(x),
+foreach_face_type
+#undef _
+};
+
+
+/* Face */
+
+int
+face_initialize(face_t * face)
+{
+ memset(face, 0, sizeof(face_t));
+ return 1;
+}
+
+int
+face_initialize_udp(face_t * face, const char * interface_name, const
+ ip_address_t * local_addr, u16 local_port,
+ const ip_address_t * remote_addr, u16 remote_port,
+ int family)
+{
+ if (!local_addr)
+ return -1;
+
+ *face = (face_t) {
+ .type = FACE_TYPE_UDP,
+ .family = family,
+ .local_addr = *local_addr,
+ .local_port = local_port,
+ .remote_addr = remote_addr ? *remote_addr : IP_ADDRESS_EMPTY,
+ .remote_port = remote_port,
+ };
+
+ snprintf(face->netdevice.name, IFNAMSIZ, "%s", interface_name);
+
+ return 1;
+}
+
+int
+face_initialize_udp_sa(face_t * face, const char * interface_name,
+ const struct sockaddr * local_addr,
+ const struct sockaddr * remote_addr)
+{
+ if (!local_addr)
+ return -1;
+
+ if (remote_addr && (local_addr->sa_family != remote_addr->sa_family))
+ return -1;
+
+ switch (local_addr->sa_family) {
+ case AF_INET:
+ {
+ struct sockaddr_in *lsai = (struct sockaddr_in *)local_addr;
+ struct sockaddr_in *rsai = (struct sockaddr_in *)remote_addr;
+ *face = (face_t) {
+ .type = FACE_TYPE_UDP,
+ .family = AF_INET,
+ .local_addr.v4.as_inaddr = lsai->sin_addr,
+ .local_port = lsai ? ntohs(lsai->sin_port) : 0,
+ .remote_addr = IP_ADDRESS_EMPTY,
+ .remote_port = rsai ? ntohs(rsai->sin_port) : 0,
+ };
+ if (rsai)
+ face->remote_addr.v4.as_inaddr = rsai->sin_addr;
+ }
+ break;
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *lsai = (struct sockaddr_in6 *)local_addr;
+ struct sockaddr_in6 *rsai = (struct sockaddr_in6 *)remote_addr;
+ *face = (face_t) {
+ .type = FACE_TYPE_UDP,
+ .family = AF_INET6,
+ .local_addr.v6.as_in6addr = lsai->sin6_addr,
+ .local_port = lsai ? ntohs(lsai->sin6_port) : 0,
+ .remote_addr = IP_ADDRESS_EMPTY,
+ .remote_port = rsai ? ntohs(rsai->sin6_port) : 0,
+ };
+ if (rsai)
+ face->remote_addr.v6.as_in6addr = rsai->sin6_addr;
+ }
+ break;
+ default:
+ return -1;
+ }
+
+ snprintf(face->netdevice.name, IFNAMSIZ, "%s", interface_name);
+
+ return 1;
+}
+
+face_t * face_create()
+{
+ face_t * face = calloc(1, sizeof(face_t));
+ return face;
+}
+
+face_t * face_create_udp(const char * interface_name,
+ const ip_address_t * local_addr, u16 local_port,
+ const ip_address_t * remote_addr, u16 remote_port, int family)
+{
+ face_t * face = face_create();
+ if (face_initialize_udp(face, interface_name, local_addr, local_port, remote_addr, remote_port, family) < 0)
+ goto ERR_INIT;
+ return face;
+
+ERR_INIT:
+ free(face);
+ return NULL;
+}
+
+face_t * face_create_udp_sa(const char * interface_name,
+ const struct sockaddr * local_addr,
+ const struct sockaddr * remote_addr)
+{
+ face_t * face = face_create();
+ if (face_initialize_udp_sa(face, interface_name, local_addr, remote_addr) < 0)
+ goto ERR_INIT;
+ return face;
+
+ERR_INIT:
+ free(face);
+ return NULL;
+}
+
+void face_free(face_t * face)
+{
+ free(face);
+}
+
+/**
+ * \brief Compare two faces
+ * \param [in] f1 - First face
+ * \param [in] f2 - Second face
+ * \return whether faces are equal, ie both their types are parameters are
+ * equal.
+ *
+ * NOTE: this function implements a partial order.
+ */
+int
+face_cmp(const face_t * f1, const face_t * f2)
+{
+
+ int ret = f1->type - f2->type;
+ if (ret != 0)
+ return ret;
+
+ ret = f1->family - f2->family;
+ if (ret != 0)
+ return ret;
+
+ /*
+ * FIXME As hicn-light API might not return the netdevice, we can discard the
+ * comparison when one of the two is not set for now...
+ */
+ if ((f1->netdevice.index != 0) && (f2->netdevice.index != 0)) {
+ ret = netdevice_cmp(&f1->netdevice, &f2->netdevice);
+ if (ret != 0)
+ return ret;
+ }
+
+ switch(f1->type) {
+ case FACE_TYPE_HICN:
+ ret = ip_address_cmp(&f1->local_addr, &f2->local_addr, f1->family);
+ if (ret != 0)
+ return ret;
+
+ ret = ip_address_cmp(&f1->remote_addr, &f2->remote_addr, f1->family);
+ if (ret != 0)
+ return ret;
+
+ break;
+
+ case FACE_TYPE_TCP:
+ case FACE_TYPE_UDP:
+ ret = ip_address_cmp(&f1->local_addr, &f2->local_addr, f1->family);
+ if (ret != 0)
+ return ret;
+
+ ret = f1->local_port - f2->local_port;
+ if (ret != 0)
+ return ret;
+
+ ret = ip_address_cmp(&f1->remote_addr, &f2->remote_addr, f1->family);
+ if (ret != 0)
+ return ret;
+
+ ret = f1->remote_port - f2->remote_port;
+ if (ret != 0)
+ return ret;
+
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+/* /!\ Please update constants in header file upon changes */
+size_t
+face_snprintf(char * s, size_t size, const face_t * face)
+{
+ switch(face->type) {
+ case FACE_TYPE_HICN:
+ {
+ char local[MAXSZ_IP_ADDRESS];
+ char remote[MAXSZ_IP_ADDRESS];
+ char tags[MAXSZ_POLICY_TAGS];
+
+ ip_address_snprintf(local, MAXSZ_IP_ADDRESS,
+ &face->local_addr,
+ face->family);
+ ip_address_snprintf(remote, MAXSZ_IP_ADDRESS,
+ &face->remote_addr,
+ face->family);
+ policy_tags_snprintf(tags, MAXSZ_POLICY_TAGS, face->tags);
+ return snprintf(s, size, "%s [%s -> %s] [%s]",
+ face_type_str(face->type),
+ local,
+ remote,
+ tags);
+ }
+ case FACE_TYPE_UNDEFINED:
+ case FACE_TYPE_TCP:
+ case FACE_TYPE_UDP:
+ {
+ char local[MAXSZ_IP_ADDRESS];
+ char remote[MAXSZ_IP_ADDRESS];
+ char tags[MAXSZ_POLICY_TAGS];
+
+ ip_address_snprintf(local, MAXSZ_IP_ADDRESS,
+ &face->local_addr,
+ face->family);
+ ip_address_snprintf(remote, MAXSZ_IP_ADDRESS,
+ &face->remote_addr,
+ face->family);
+ policy_tags_snprintf(tags, MAXSZ_POLICY_TAGS, face->tags);
+
+ return snprintf(s, size, "%s [%s:%d -> %s:%d] [%s]",
+ face_type_str(face->type),
+ local,
+ face->local_port,
+ remote,
+ face->remote_port,
+ tags);
+ }
+ default:
+ return -1;
+ }
+
+}
+
+policy_tags_t face_get_tags(const face_t * face)
+{
+ return face->tags;
+}
+
+int
+face_set_tags(face_t * face, policy_tags_t tags)
+{
+ face->tags = tags;
+ return 1;
+}
diff --git a/lib/src/util/ip_address.c b/lib/src/util/ip_address.c
index 49916547d..d4b34dc0b 100644
--- a/lib/src/util/ip_address.c
+++ b/lib/src/util/ip_address.c
@@ -302,10 +302,13 @@ ip_prefix_ntop(const ip_prefix_t * ip_prefix, char *dst, size_t size)
}
if (!s)
return -1;
- int rc = snprintf(dst, size, "%s/%d", ip_s, ip_prefix->len);
- if (rc >= size)
- return (int)size;
- return rc;
+ return snprintf(dst, size, "%s/%d", ip_s, ip_prefix->len);
+}
+
+int
+ip_prefix_snprintf(char * s, size_t size, const ip_prefix_t * prefix)
+{
+ return ip_prefix_ntop(prefix, s, size);
}
int