diff options
author | Angelo Mantellini <angelo.mantellini@cisco.com> | 2020-03-31 17:50:43 +0200 |
---|---|---|
committer | Jordan Augé <jordan.auge+fdio@cisco.com> | 2020-04-27 11:26:51 +0200 |
commit | 15ad172a847fa667c57a4594ef4158405db9a984 (patch) | |
tree | 80c0bd083d7f206774f2b8fb3d0dacec06fde24f /lib | |
parent | 23c3bb7400839b664096ad5e16a2346386109bda (diff) |
[HICN-554] hicn-light refactoring
Change-Id: I36f2d393741d4502ce14d3791158e43e3e9cd4cf
Signed-off-by: Jordan Augé <jordan.auge+fdio@cisco.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/includes/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/includes/hicn/base.h | 9 | ||||
-rw-r--r-- | lib/includes/hicn/face.h | 213 | ||||
-rw-r--r-- | lib/includes/hicn/policy.h | 64 | ||||
-rw-r--r-- | lib/includes/hicn/protocol/tcp.h | 6 | ||||
-rw-r--r-- | lib/includes/hicn/util/ip_address.h | 2 | ||||
-rw-r--r-- | lib/src/CMakeLists.txt | 6 | ||||
-rw-r--r-- | lib/src/face.c | 422 | ||||
-rw-r--r-- | lib/src/util/ip_address.c | 11 |
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 |