summaryrefslogtreecommitdiffstats
path: root/ctrl/facemgr/src/cfg.c
diff options
context:
space:
mode:
Diffstat (limited to 'ctrl/facemgr/src/cfg.c')
-rw-r--r--ctrl/facemgr/src/cfg.c991
1 files changed, 991 insertions, 0 deletions
diff --git a/ctrl/facemgr/src/cfg.c b/ctrl/facemgr/src/cfg.c
new file mode 100644
index 000000000..6b04208bb
--- /dev/null
+++ b/ctrl/facemgr/src/cfg.c
@@ -0,0 +1,991 @@
+/**
+ * \file cfg.c
+ * \brief Implementation of Face manager configuration
+ */
+
+#include <assert.h>
+#include <hicn/ctrl.h> // HICN_DEFAULT_PORT
+#include <hicn/facemgr/cfg.h>
+#include <hicn/policy.h>
+#include <hicn/util/ip_address.h>
+#include "util/set.h"
+
+/* Overlay */
+
+typedef struct {
+ bool is_local_port;
+ uint16_t local_port;
+ bool is_local_addr;
+ ip_address_t local_addr;
+ bool is_remote_port;
+ uint16_t remote_port;
+ bool is_remote_addr;
+ ip_address_t remote_addr;
+} facemgr_cfg_overlay_t;
+
+int
+facemgr_cfg_overlay_initialize(facemgr_cfg_overlay_t * overlay)
+{
+ overlay->is_local_port = false;
+ overlay->local_port = 0;
+ overlay->is_local_addr = false;
+ overlay->local_addr = IP_ADDRESS_EMPTY;
+
+ overlay->is_remote_port = false;
+ overlay->remote_port = 0;
+ overlay->is_remote_addr = false;
+ overlay->remote_addr = IP_ADDRESS_EMPTY;
+
+ return 0;
+}
+
+int
+facemgr_cfg_overlay_finalize(facemgr_cfg_overlay_t * overlay)
+{
+ return 0;
+}
+
+facemgr_cfg_overlay_t * facemgr_cfg_overlay_create()
+{
+ facemgr_cfg_overlay_t * overlay = malloc(sizeof(facemgr_cfg_overlay_t));
+ if (!overlay)
+ return NULL;
+
+ int rc = facemgr_cfg_overlay_initialize(overlay);
+ if (rc < 0) {
+ free(overlay);
+ return NULL;
+ }
+
+ return overlay;
+}
+
+void facemgr_cfg_overlay_free(facemgr_cfg_overlay_t * overlay)
+{
+ facemgr_cfg_overlay_finalize(overlay);
+ free(overlay);
+}
+
+typedef struct {
+ facemgr_cfg_overlay_t * v4;
+ facemgr_cfg_overlay_t * v6;
+} facemgr_cfg_overlays_t;
+
+typedef struct {
+ const char * interface_name;
+ netdevice_type_t interface_type;
+} facemgr_cfg_match_t;
+
+
+typedef struct {
+ /* Interface specific */
+ bool is_face_type; // default is auto
+ facemgr_face_type_t face_type;
+
+ /* This should be defaut for the global settings */
+ bool is_ignore;
+ bool ignore;
+ bool is_discovery;
+ bool discovery;
+ bool is_ipv4;
+ bool ipv4;
+ bool is_ipv6;
+ bool ipv6;
+
+ facemgr_cfg_overlays_t overlays; // fallback unless discovery is disabled
+} facemgr_cfg_override_t;
+
+struct facemgr_cfg_rule_s {
+ facemgr_cfg_match_t match;
+ facemgr_cfg_override_t override;
+};
+
+int
+facemgr_cfg_override_initialize(facemgr_cfg_override_t * override)
+{
+ override->is_face_type = false;
+ override->face_type = FACEMGR_FACE_TYPE_UNDEFINED;
+
+ override->is_ignore = false;
+ override->ignore = false;
+
+ override->is_discovery = false;
+ override->discovery = false;
+
+ override->overlays.v4 = NULL;
+ override->overlays.v6 = NULL;
+
+ return 0;
+}
+
+int
+facemgr_cfg_override_finalize(facemgr_cfg_override_t * override)
+{
+ if (override->overlays.v4) {
+ facemgr_cfg_overlay_free(override->overlays.v4);
+ override->overlays.v4 = NULL;
+ }
+ if (override->overlays.v6) {
+ facemgr_cfg_overlay_free(override->overlays.v6);
+ override->overlays.v6 = NULL;
+ }
+
+ return 0;
+}
+
+
+/* Rule */
+facemgr_cfg_rule_t * facemgr_cfg_rule_create()
+{
+ facemgr_cfg_rule_t * rule = malloc(sizeof(facemgr_cfg_rule_t));
+ if (!rule)
+ return NULL;
+
+ int rc = facemgr_cfg_rule_initialize(rule);
+ if (rc < 0)
+ return NULL;
+
+ return rule;
+}
+
+void facemgr_cfg_rule_free(facemgr_cfg_rule_t * rule)
+{
+ facemgr_cfg_rule_finalize(rule);
+ free(rule);
+}
+
+int
+facemgr_cfg_rule_initialize(facemgr_cfg_rule_t * rule)
+{
+ rule->match.interface_name = NULL;
+ rule->match.interface_type = NETDEVICE_TYPE_UNDEFINED;
+
+ int rc = facemgr_cfg_override_initialize(&rule->override);
+ if (rc < 0)
+ return -1;
+
+ return 0;
+}
+
+int
+facemgr_cfg_rule_finalize(facemgr_cfg_rule_t * rule)
+{
+ if (rule->match.interface_name) {
+ free((void*)rule->match.interface_name);
+ rule->match.interface_name = NULL;
+ }
+ return facemgr_cfg_override_finalize(&rule->override);
+}
+
+void
+facemgr_cfg_rule_dump(facemgr_cfg_rule_t * rule)
+{
+ DEBUG(" <rule>");
+ DEBUG(" <match interface_name=%s interface_type=%s>",
+ rule->match.interface_name,
+ netdevice_type_str[rule->match.interface_type]);
+ DEBUG(" <override>");
+ if (rule->override.is_face_type) {
+ DEBUG(" <face_type>%d</face_type>", rule->override.face_type);
+ }
+ if (rule->override.is_ignore) {
+ DEBUG(" <ignore>%d</ignore>", rule->override.ignore);
+ }
+ if (rule->override.is_discovery) {
+ DEBUG(" <discovery>%d</discovery>", rule->override.discovery);
+ }
+ if (rule->override.is_ipv4) {
+ DEBUG(" <ipv4>%d</ipv4>", rule->override.ipv4);
+ }
+ if (rule->override.is_ipv6) {
+ DEBUG(" <ipv6>%d</ipv6>", rule->override.ipv6);
+ }
+ DEBUG(" <overlays>");
+ if (rule->override.overlays.v4) {
+ DEBUG(" <ipv4>");
+ if (rule->override.overlays.v4->is_local_addr) {
+ char buf[MAXSZ_IP_ADDRESS];
+ ip_address_snprintf(buf, MAXSZ_IP_ADDRESS,
+ &rule->override.overlays.v4->local_addr, AF_INET);
+ DEBUG(" <local_addr>%s</local_addr>", buf);
+ }
+ if (rule->override.overlays.v4->is_local_port) {
+ DEBUG(" <local_port>%d</local_port>",
+ rule->override.overlays.v4->local_port);
+ }
+ if (rule->override.overlays.v4->is_remote_addr) {
+ char buf[MAXSZ_IP_ADDRESS];
+ ip_address_snprintf(buf, MAXSZ_IP_ADDRESS,
+ &rule->override.overlays.v4->remote_addr, AF_INET);
+ DEBUG(" <remote_addr>%s</remote_addr>", buf);
+ }
+ if (rule->override.overlays.v4->is_remote_port) {
+ DEBUG(" <remote_port>%d</remote_port>",
+ rule->override.overlays.v4->remote_port);
+ }
+ DEBUG(" </ipv4>");
+ }
+ if (rule->override.overlays.v6) {
+ DEBUG(" <ipv6>");
+ if (rule->override.overlays.v6->is_local_addr) {
+ char buf[MAXSZ_IP_ADDRESS];
+ ip_address_snprintf(buf, MAXSZ_IP_ADDRESS,
+ &rule->override.overlays.v6->local_addr, AF_INET6);
+ DEBUG(" <local_addr>%s</local_addr>", buf);
+ }
+ if (rule->override.overlays.v6->is_local_port) {
+ DEBUG(" <local_port>%d</local_port>",
+ rule->override.overlays.v6->local_port);
+ }
+ if (rule->override.overlays.v6->is_remote_addr) {
+ char buf[MAXSZ_IP_ADDRESS];
+ ip_address_snprintf(buf, MAXSZ_IP_ADDRESS,
+ &rule->override.overlays.v6->remote_addr, AF_INET6);
+ DEBUG(" <remote_addr>%s</remote_addr>", buf);
+ }
+ if (rule->override.overlays.v6->is_remote_port) {
+ DEBUG(" <remote_port>%d</remote_port>",
+ rule->override.overlays.v6->remote_port);
+ }
+ DEBUG(" </ipv6>");
+ }
+ DEBUG(" </overlays>");
+ DEBUG(" </override>");
+ DEBUG(" </rule>");
+}
+
+int
+facemgr_cfg_rule_set_match(facemgr_cfg_rule_t * rule, const char * interface_name,
+ netdevice_type_t interface_type)
+{
+ rule->match.interface_name = interface_name ? strdup(interface_name) : NULL;
+ rule->match.interface_type = interface_type;
+ return 0;
+}
+
+int
+facemgr_cfg_rule_set_face_type(facemgr_cfg_rule_t * rule, facemgr_face_type_t * face_type)
+{
+ rule->override.is_face_type = true;
+ rule->override.face_type = *face_type;
+ return 0;
+}
+
+int
+facemgr_cfg_rule_unset_face_type(facemgr_cfg_rule_t * rule)
+{
+ rule->override.is_face_type = false;
+ rule->override.face_type = FACEMGR_FACE_TYPE_UNDEFINED; /* optional */
+ return 0;
+}
+
+int
+facemgr_cfg_rule_set_discovery(facemgr_cfg_rule_t * rule, bool status)
+{
+ rule->override.is_discovery = true;
+ rule->override.discovery = status;
+ return 0;
+}
+
+int
+facemgr_cfg_rule_unset_discovery(facemgr_cfg_rule_t * rule)
+{
+ rule->override.is_discovery = false;
+ return 0;
+}
+
+int
+facemgr_cfg_rule_set_ignore(facemgr_cfg_rule_t * rule, bool status)
+{
+ rule->override.is_ignore = true;
+ rule->override.ignore = status;
+ return 0;
+}
+
+int
+facemgr_cfg_rule_unset_ignore(facemgr_cfg_rule_t * rule)
+{
+ rule->override.is_ignore = false;
+ return 0;
+}
+
+int
+facemgr_cfg_rule_set_ipv4(facemgr_cfg_rule_t * rule, bool status)
+{
+ rule->override.is_ipv4 = true;
+ rule->override.ipv4 = status;
+ return 0;
+}
+
+int
+facemgr_cfg_rule_unset_ipv4(facemgr_cfg_rule_t * rule)
+{
+ rule->override.is_ipv4 = false;
+ return 0;
+}
+
+int
+facemgr_cfg_rule_set_ipv6(facemgr_cfg_rule_t * rule, bool status)
+{
+ rule->override.is_ipv6 = true;
+ rule->override.ipv6 = status;
+ return 0;
+}
+
+int
+facemgr_cfg_rule_unset_ipv6(facemgr_cfg_rule_t * rule)
+{
+ rule->override.is_ipv6 = false;
+ return 0;
+}
+
+int
+facemgr_cfg_rule_set_overlay(facemgr_cfg_rule_t * rule, int family,
+ ip_address_t * local_addr, uint16_t local_port,
+ ip_address_t * remote_addr, uint16_t remote_port) {
+ if ((family != AF_INET) && (family != AF_INET6))
+ return -1;
+
+ facemgr_cfg_overlay_t * overlay = facemgr_cfg_overlay_create();
+ if (local_addr) {
+ overlay->is_local_addr = true;
+ overlay->local_addr = *local_addr;
+ }
+ if (IS_VALID_PORT(local_port)) {
+ overlay->is_local_port = true;
+ overlay->local_port = local_port;
+ }
+ if (remote_addr) {
+ overlay->is_remote_addr = true;
+ overlay->remote_addr = *remote_addr;
+ }
+ if (IS_VALID_PORT(remote_port)) {
+ overlay->is_remote_port = true;
+ overlay->remote_port = remote_port;
+ }
+
+ switch(family) {
+ case AF_INET:
+ rule->override.overlays.v4 = overlay;
+ break;
+
+ case AF_INET6:
+ rule->override.overlays.v6 = overlay;
+ break;
+
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+facemgr_rule_unset_overlay(facemgr_cfg_rule_t * rule, int family)
+{
+ if ((family != AF_INET) && (family != AF_INET6) && (family != AF_UNSPEC))
+ return -1;
+
+ if ((family == AF_UNSPEC) || (family == AF_INET)) {
+ if (rule->override.overlays.v4) {
+ facemgr_cfg_overlay_free(rule->override.overlays.v4);
+ rule->override.overlays.v4 = NULL;
+ }
+ }
+ if ((family == AF_UNSPEC) || (family == AF_INET6)) {
+ if (rule->override.overlays.v6) {
+ facemgr_cfg_overlay_free(rule->override.overlays.v6);
+ rule->override.overlays.v6 = NULL;
+ }
+ }
+ return 0;
+}
+
+int
+facemgr_cfg_rule_cmp(const facemgr_cfg_rule_t * r1, const facemgr_cfg_rule_t * r2)
+{
+ /*
+ * We implement a lexicographic order on the tuple (interface_name,
+ * interface_type)
+ */
+
+ /* We need to handle NULL cases out of strcmp */
+ if (!r1->match.interface_name) {
+ if (r2->match.interface_name)
+ return 1;
+ else
+ goto BOTH_NULL;
+ } else {
+ if (!r2->match.interface_name)
+ return -1;
+ }
+
+
+ /* Only if both are non-NULL, we proceed to strcmp */
+ int rc = strcmp(r1->match.interface_name, r2->match.interface_name);
+ if (rc != 0)
+ return rc;
+
+BOTH_NULL:
+ return r1->match.interface_type - r2->match.interface_type;
+}
+
+/* General */
+
+TYPEDEF_SET_H(facemgr_cfg_rule_set, facemgr_cfg_rule_t *);
+TYPEDEF_SET(facemgr_cfg_rule_set, facemgr_cfg_rule_t *, facemgr_cfg_rule_cmp, generic_snprintf);
+
+struct facemgr_cfg_s {
+ facemgr_cfg_override_t global;
+ facemgr_cfg_rule_set_t * rule_set;
+ //log_cfg_t log;
+};
+
+facemgr_cfg_t * facemgr_cfg_create()
+{
+ facemgr_cfg_t * cfg = malloc(sizeof(facemgr_cfg_t));
+ if (!cfg)
+ return NULL;
+
+ int rc = facemgr_cfg_initialize(cfg);
+ if (rc < 0) {
+ free(cfg);
+ return NULL;
+ }
+
+ return cfg;
+}
+
+void facemgr_cfg_free(facemgr_cfg_t * cfg)
+{
+ facemgr_cfg_finalize(cfg);
+ free(cfg);
+}
+
+int
+facemgr_cfg_initialize(facemgr_cfg_t * cfg)
+{
+ int rc = facemgr_cfg_override_initialize(&cfg->global);
+ if (rc < 0)
+ goto ERR_OVERRIDE;
+
+ cfg->rule_set = facemgr_cfg_rule_set_create();
+ if (!cfg->rule_set)
+ goto ERR_RULE_SET;
+
+ return 0;
+
+ERR_RULE_SET:
+ facemgr_cfg_override_finalize(&cfg->global);
+ERR_OVERRIDE:
+ return -1;
+}
+
+int
+facemgr_cfg_finalize(facemgr_cfg_t * cfg)
+{
+ /* TODO Free all rules */
+ facemgr_cfg_rule_set_free(cfg->rule_set);
+ return facemgr_cfg_override_finalize(&cfg->global);
+}
+
+void facemgr_cfg_dump(facemgr_cfg_t * cfg)
+{
+ return; /* NOT IMPLEMENTED */
+}
+
+/* General */
+int
+facemgr_cfg_set_face_type(facemgr_cfg_t * cfg, facemgr_face_type_t * face_type)
+{
+ cfg->global.is_face_type = true;
+ cfg->global.face_type = *face_type;
+ return 0;
+}
+
+int
+facemgr_cfg_unset_face_type(facemgr_cfg_t * cfg)
+{
+ cfg->global.is_face_type = false;
+ cfg->global.face_type = FACEMGR_FACE_TYPE_UNDEFINED; /* optional */
+ return 0;
+}
+
+int
+facemgr_cfg_set_discovery(facemgr_cfg_t * cfg, bool status)
+{
+ cfg->global.is_discovery = true;
+ cfg->global.discovery = status;
+ return 0;
+}
+
+int
+facemgr_cfg_unset_discovery(facemgr_cfg_t * cfg)
+{
+ cfg->global.is_discovery = false;
+ return 0;
+}
+
+int
+facemgr_cfg_set_overlay(facemgr_cfg_t * cfg, int family,
+ ip_address_t * local_addr, uint16_t local_port,
+ ip_address_t * remote_addr, uint16_t remote_port)
+{
+ if ((family != AF_INET) && (family != AF_INET6))
+ return -1;
+
+ facemgr_cfg_overlay_t * overlay = facemgr_cfg_overlay_create();
+ if (local_addr) {
+ overlay->is_local_addr = true;
+ overlay->local_addr = *local_addr;
+ }
+ if (IS_VALID_PORT(local_port)) {
+ overlay->is_local_port = true;
+ overlay->local_port = local_port;
+ }
+ if (remote_addr) {
+ overlay->is_remote_addr = true;
+ overlay->remote_addr = *remote_addr;
+ }
+ if (IS_VALID_PORT(remote_port)) {
+ overlay->is_remote_port = true;
+ overlay->remote_port = remote_port;
+ }
+
+ DEBUG("facemgr_cfg_set_overlay");
+
+ switch(family) {
+ case AF_INET:
+ cfg->global.overlays.v4 = overlay;
+ break;
+
+ case AF_INET6:
+ cfg->global.overlays.v6 = overlay;
+ break;
+
+ default:
+ return -1;
+ }
+
+ DEBUG("<global>");
+ DEBUG(" <overlay>");
+ if (overlay) {
+ DEBUG(" <ipv4>");
+ if (overlay->is_local_addr) {
+ char buf[MAXSZ_IP_ADDRESS];
+ ip_address_snprintf(buf, MAXSZ_IP_ADDRESS,
+ &overlay->local_addr, AF_INET);
+ DEBUG(" <local_addr>%s</local_addr>", buf);
+ }
+ if (overlay->is_local_port) {
+ DEBUG(" <local_port>%d</local_port>",
+ overlay->local_port);
+ }
+ if (overlay->is_remote_addr) {
+ char buf[MAXSZ_IP_ADDRESS];
+ ip_address_snprintf(buf, MAXSZ_IP_ADDRESS,
+ &overlay->remote_addr, AF_INET);
+ DEBUG(" <remote_addr>%s</remote_addr>", buf);
+ }
+ if (overlay->is_remote_port) {
+ DEBUG(" <remote_port>%d</remote_port>",
+ overlay->remote_port);
+ }
+ DEBUG(" </ipv4>");
+ }
+ DEBUG(" </overlay>");
+ DEBUG("</global>");
+
+ return 0;
+}
+
+int
+facemgr_cfg_unset_overlay(facemgr_cfg_t * cfg, int family)
+{
+ if ((family != AF_INET) && (family != AF_INET6) && (family != AF_UNSPEC))
+ return -1;
+
+ if ((family == AF_UNSPEC) || (family == AF_INET)) {
+ if (cfg->global.overlays.v4) {
+ facemgr_cfg_overlay_free(cfg->global.overlays.v4);
+ cfg->global.overlays.v4 = NULL;
+ }
+ }
+ if ((family == AF_UNSPEC) || (family == AF_INET6)) {
+ if (cfg->global.overlays.v6) {
+ facemgr_cfg_overlay_free(cfg->global.overlays.v6);
+ cfg->global.overlays.v6 = NULL;
+ }
+ }
+ return 0;
+}
+
+int
+facemgr_cfg_add_rule(facemgr_cfg_t * cfg, facemgr_cfg_rule_t * rule)
+{
+ facemgr_cfg_rule_dump(rule);
+ return facemgr_cfg_rule_set_add(cfg->rule_set, rule);
+}
+
+int
+facemgr_cfg_del_rule(facemgr_cfg_t * cfg, facemgr_cfg_rule_t * rule)
+{
+ return facemgr_cfg_rule_set_remove(cfg->rule_set, rule, NULL);
+}
+
+int facemgr_cfg_get_rule(const facemgr_cfg_t * cfg, const char * interface_name,
+ netdevice_type_t interface_type, facemgr_cfg_rule_t ** rule) {
+ facemgr_cfg_rule_t rule_search = {
+ .match = {
+ .interface_name = interface_name,
+ .interface_type = interface_type,
+ },
+ };
+ return facemgr_cfg_rule_set_get(cfg->rule_set, &rule_search, rule);
+}
+
+/* Query API */
+
+/*
+ * Check whether there are override rules for the given netdevice
+ *
+ * TODO:
+ * - until we have proper indexes we loop through the whole structure
+ */
+int
+facemgr_cfg_get_override(const facemgr_cfg_t * cfg,
+ const netdevice_t * netdevice, netdevice_type_t netdevice_type,
+ facemgr_cfg_override_t ** override)
+{
+ if (!netdevice) {
+ *override = NULL;
+ return 0;
+ }
+
+ facemgr_cfg_rule_t **rule_array;
+ int rc = facemgr_cfg_rule_set_get_array(cfg->rule_set, &rule_array);
+ if (rc < 0) {
+ ERROR("facemgr_cfg_rule_set_get_array failed");
+ return rc;
+ }
+ for (unsigned i = 0; i < rc; i++) {
+ const char * interface_name = rule_array[i]->match.interface_name;
+ /* Check match for interface name */
+ if (interface_name && (strcmp(interface_name, netdevice->name) != 0))
+ continue;
+ /* Check match for interface type */
+ if (rule_array[i]->match.interface_type != NETDEVICE_TYPE_UNDEFINED) {
+#ifdef __ANDROID__
+ if (netdevice_type != rule_array[i]->match.interface_type)
+ continue;
+#else
+ ERROR("Match on interface type is currently not implemented");
+ goto ERR_ARRAY;
+#endif /* __ANDROID__ */
+ }
+ /* Found match... do we have an override for face_type */
+ DEBUG("override found nd=%s, ndt=%s", rule_array[i]->match.interface_name, netdevice_type_str[rule_array[i]->match.interface_type]);
+ *override = &rule_array[i]->override;
+ goto FOUND;
+ }
+
+ DEBUG("override not found");
+ *override = NULL;
+
+FOUND:
+ free(rule_array);
+ return 0;
+
+#ifndef __ANDROID__
+ERR_ARRAY:
+ free(rule_array);
+ return -1;
+#endif /* __ANDROID__ */
+}
+
+int
+facemgr_cfg_get_face_type(const facemgr_cfg_t * cfg,
+ const netdevice_t * netdevice, netdevice_type_t netdevice_type,
+ facemgr_face_type_t * face_type)
+{
+ facemgr_cfg_override_t * override;
+ int rc = facemgr_cfg_get_override(cfg, netdevice, netdevice_type,
+ &override);
+ if (rc < 0) {
+ ERROR("get override failed");
+ return rc;
+ }
+
+ if ((override) && (override->is_face_type)) {
+ *face_type = override->face_type;
+ return 0;
+ }
+
+ *face_type = cfg->global.is_face_type
+ ? cfg->global.face_type
+ : FACEMGR_FACE_TYPE_DEFAULT;
+
+ return 0;
+}
+
+int
+facemgr_cfg_get_discovery(const facemgr_cfg_t * cfg,
+ const netdevice_t * netdevice, netdevice_type_t netdevice_type,
+ bool * discovery)
+{
+ facemgr_cfg_override_t * override;
+ int rc = facemgr_cfg_get_override(cfg, netdevice, netdevice_type,
+ &override);
+ if (rc < 0)
+ return rc;
+
+ if ((override) && (override->is_discovery)) {
+ *discovery = override->discovery;
+ return 0;
+ }
+
+ *discovery = cfg->global.is_discovery
+ ? cfg->global.discovery
+ : FACEMGR_CFG_DEFAULT_DISCOVERY;
+ return 0;
+}
+
+int
+facemgr_cfg_get_ipv4(const facemgr_cfg_t * cfg,
+ const netdevice_t * netdevice, netdevice_type_t netdevice_type,
+ bool * ipv4)
+{
+ facemgr_cfg_override_t * override;
+ int rc = facemgr_cfg_get_override(cfg, netdevice, netdevice_type,
+ &override);
+ if (rc < 0)
+ return rc;
+
+ if ((override) && (override->is_ipv4)) {
+ *ipv4 = override->ipv4;
+ return 0;
+ }
+
+ *ipv4 = cfg->global.is_ipv4
+ ? cfg->global.ipv4
+ : FACEMGR_CFG_DEFAULT_IPV4;
+ return 0;
+}
+
+int
+facemgr_cfg_get_ipv6(const facemgr_cfg_t * cfg,
+ const netdevice_t * netdevice, netdevice_type_t netdevice_type,
+ bool * ipv6)
+{
+ facemgr_cfg_override_t * override;
+ int rc = facemgr_cfg_get_override(cfg, netdevice, netdevice_type,
+ &override);
+ if (rc < 0)
+ return rc;
+
+ if ((override) && (override->is_ipv6)) {
+ *ipv6 = override->ipv6;
+ return 0;
+ }
+
+ *ipv6 = cfg->global.is_ipv6
+ ? cfg->global.ipv6
+ : FACEMGR_CFG_DEFAULT_IPV6;
+ return 0;
+}
+
+int
+facemgr_cfg_get_ignore(const facemgr_cfg_t * cfg,
+ const netdevice_t * netdevice, netdevice_type_t netdevice_type,
+ bool * ignore)
+{
+ facemgr_cfg_override_t * override;
+ int rc = facemgr_cfg_get_override(cfg, netdevice, netdevice_type,
+ &override);
+ if (rc < 0)
+ return rc;
+
+ if ((override) && (override->is_ignore)) {
+ *ignore = override->ignore;
+ return 0;
+ }
+
+ assert (!cfg->global.is_ignore);
+
+ *ignore = (netdevice && (netdevice->name[0] != '\0') && strcmp(netdevice->name, "lo") == 0);
+
+ return 0;
+}
+
+int
+facemgr_cfg_get_overlay_local_addr(const facemgr_cfg_t * cfg,
+ const netdevice_t * netdevice, netdevice_type_t netdevice_type,
+ int family, ip_address_t * addr)
+{
+ facemgr_cfg_override_t * override;
+ int rc = facemgr_cfg_get_override(cfg, netdevice, netdevice_type,
+ &override);
+ if (rc < 0)
+ return rc;
+
+ switch (family) {
+ case AF_INET:
+ if ((override) && (override->overlays.v4) && (override->overlays.v4->is_local_addr)) {
+ *addr = override->overlays.v4->local_addr;
+ return 0;
+ }
+ if ((cfg->global.overlays.v4) && (cfg->global.overlays.v4->is_local_addr)) {
+ *addr = cfg->global.overlays.v4->local_addr;
+ return 0;
+ }
+ break;
+ case AF_INET6:
+ if ((override) && (override->overlays.v6) && (override->overlays.v6->is_local_addr)) {
+ *addr = override->overlays.v6->local_addr;
+ return 0;
+ }
+ if ((cfg->global.overlays.v6) && (cfg->global.overlays.v6->is_local_addr)) {
+ *addr = cfg->global.overlays.v6->local_addr;
+ return 0;
+ }
+ break;
+ case AF_UNSPEC:
+ break;
+ default:
+ return -1;
+ }
+
+ *addr = IP_ADDRESS_EMPTY;
+ return 0;
+}
+
+int
+facemgr_cfg_get_overlay_local_port(const facemgr_cfg_t * cfg,
+ const netdevice_t * netdevice, netdevice_type_t netdevice_type,
+ int family, u16 * port)
+{
+ facemgr_cfg_override_t * override;
+ int rc = facemgr_cfg_get_override(cfg, netdevice, netdevice_type,
+ &override);
+ if (rc < 0)
+ return rc;
+
+ switch (family) {
+ case AF_INET:
+ if ((override) && (override->overlays.v4) && (override->overlays.v4->is_local_port)) {
+ *port = override->overlays.v4->local_port;
+ return 0;
+ }
+ if ((cfg->global.overlays.v4) && (cfg->global.overlays.v4->is_local_port)) {
+ *port = cfg->global.overlays.v4->local_port;
+ return 0;
+ }
+ break;
+ case AF_INET6:
+ if ((override) && (override->overlays.v6) && (override->overlays.v6->is_local_port)) {
+ *port = override->overlays.v6->local_port;
+ return 0;
+ }
+ if ((cfg->global.overlays.v6) && (cfg->global.overlays.v6->is_local_port)) {
+ *port = cfg->global.overlays.v6->local_port;
+ return 0;
+ }
+ break;
+ case AF_UNSPEC:
+ break;
+ default:
+ return -1;
+ }
+
+ *port = HICN_DEFAULT_PORT;
+ return 0;
+}
+
+int
+facemgr_cfg_get_overlay_remote_addr(const facemgr_cfg_t * cfg,
+ const netdevice_t * netdevice, netdevice_type_t netdevice_type,
+ int family, ip_address_t * addr)
+{
+ facemgr_cfg_override_t * override;
+ int rc = facemgr_cfg_get_override(cfg, netdevice, netdevice_type,
+ &override);
+ if (rc < 0)
+ return rc;
+
+ switch (family) {
+ case AF_INET:
+ if ((override) && (override->overlays.v4) && (override->overlays.v4->is_remote_addr)) {
+ DEBUG("remote addr v4 from override");
+ *addr = override->overlays.v4->remote_addr;
+ return 0;
+ }
+ if ((cfg->global.overlays.v4) && (cfg->global.overlays.v4->is_remote_addr)) {
+ DEBUG("remote addr v4 from global");
+ *addr = cfg->global.overlays.v4->remote_addr;
+ return 0;
+ }
+ break;
+ case AF_INET6:
+ if ((override) && (override->overlays.v6) && (override->overlays.v6->is_remote_addr)) {
+ DEBUG("remote addr v6 from override");
+ *addr = override->overlays.v6->remote_addr;
+ return 0;
+ }
+ if ((cfg->global.overlays.v6) && (cfg->global.overlays.v6->is_remote_addr)) {
+ DEBUG("remote addr v6 from global");
+ *addr = cfg->global.overlays.v6->remote_addr;
+ return 0;
+ }
+ break;
+ case AF_UNSPEC:
+ break;
+ default:
+ return -1;
+ }
+
+ DEBUG("remote addr empty");
+ *addr = IP_ADDRESS_EMPTY;
+ return 0;
+}
+
+int
+facemgr_cfg_get_overlay_remote_port(const facemgr_cfg_t * cfg,
+ const netdevice_t * netdevice, netdevice_type_t netdevice_type,
+ int family, u16 * port)
+{
+ facemgr_cfg_override_t * override;
+ int rc = facemgr_cfg_get_override(cfg, netdevice, netdevice_type,
+ &override);
+ if (rc < 0)
+ return rc;
+
+ switch (family) {
+ case AF_INET:
+ if ((override) && (override->overlays.v4) && (override->overlays.v4->is_remote_port)) {
+ *port = override->overlays.v4->remote_port;
+ return 0;
+ }
+ if ((cfg->global.overlays.v4) && (cfg->global.overlays.v4->is_remote_port)) {
+ *port = cfg->global.overlays.v4->remote_port;
+ return 0;
+ }
+ break;
+ case AF_INET6:
+ if ((override) && (override->overlays.v6) && (override->overlays.v6->is_remote_port)) {
+ *port = override->overlays.v6->remote_port;
+ return 0;
+ }
+ if ((cfg->global.overlays.v6) && (cfg->global.overlays.v6->is_remote_port)) {
+ *port = cfg->global.overlays.v6->remote_port;
+ return 0;
+ }
+ break;
+ case AF_UNSPEC:
+ break;
+ default:
+ return -1;
+ }
+
+ *port = HICN_DEFAULT_PORT;
+ return 0;
+}