aboutsummaryrefslogtreecommitdiffstats
path: root/ctrl/facemgr
diff options
context:
space:
mode:
authorJordan Augé <jordan.auge+fdio@cisco.com>2019-11-05 12:56:37 +0100
committerJordan Augé <jordan.auge+fdio@cisco.com>2019-11-17 01:01:47 +0100
commita2efba68e8fc25459ee524e31fc7228ee62d89ce (patch)
treeb3dadbbd105b224d90f1a2abd6aaca39e52587fa /ctrl/facemgr
parent5d45b1b26fd4671d8ad2dabee7631ab499862487 (diff)
[HICN-378] Add a maximum number of reattempts in face manager before entering face ignore mode
Change-Id: Id6f8cc958d3c50027475d72d80eed6b65ac0996b Signed-off-by: Jordan Augé <jordan.auge+fdio@cisco.com>
Diffstat (limited to 'ctrl/facemgr')
-rw-r--r--ctrl/facemgr/includes/hicn/facemgr/facelet.h24
-rw-r--r--ctrl/facemgr/src/api.c59
-rw-r--r--ctrl/facemgr/src/facelet.c46
-rw-r--r--ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c16
4 files changed, 109 insertions, 36 deletions
diff --git a/ctrl/facemgr/includes/hicn/facemgr/facelet.h b/ctrl/facemgr/includes/hicn/facemgr/facelet.h
index 476858eff..f2e3a82b4 100644
--- a/ctrl/facemgr/includes/hicn/facemgr/facelet.h
+++ b/ctrl/facemgr/includes/hicn/facemgr/facelet.h
@@ -33,6 +33,8 @@
#define MAXSZ_FACELET 1024
+#define FACELET_MAX_ERRORS 10
+
/* NOTE: Any test should be sufficient */
#define IS_VALID_NETDEVICE(netdevice) ((netdevice.index != 0) && (netdevice.name[0] != '\0'))
@@ -116,6 +118,23 @@ typedef enum {
extern const char * facelet_status_str[];
+/* Facelet error reason */
+#define foreach_facelet_error_reason \
+ _(UNDEFINED) \
+ _(UNSPECIFIED_ERROR) \
+ _(FORWARDER_OFFLINE) \
+ _(PERMISSION_DENIED) \
+ _(INTERNAL_ERROR) \
+ _(N)
+
+typedef enum {
+#define _(x) FACELET_ERROR_REASON_ ## x,
+ foreach_facelet_error_reason
+#undef _
+} facelet_error_reason_t;
+
+extern const char * facelet_error_reason_str[];
+
/* Facelet attribute status */
/*
@@ -234,8 +253,9 @@ int facelet_merge(facelet_t * facelet, const facelet_t * facelet_to_merge);
facelet_status_t facelet_get_status(const facelet_t * facelet);
void facelet_set_status(facelet_t * facelet, facelet_status_t status);
-void facelet_set_status_error(facelet_t * facelet, bool value);
-bool facelet_get_status_error(const facelet_t * facelet);
+void facelet_set_error(facelet_t * facelet, facelet_error_reason_t reason);
+void facelet_unset_error(facelet_t * facelet);
+bool facelet_get_error(const facelet_t * facelet);
void facelet_set_bj_done(facelet_t * facelet);
void facelet_unset_bj_done(facelet_t * facelet);
diff --git a/ctrl/facemgr/src/api.c b/ctrl/facemgr/src/api.c
index c1f7eeffa..86d6e40b6 100644
--- a/ctrl/facemgr/src/api.c
+++ b/ctrl/facemgr/src/api.c
@@ -491,6 +491,7 @@ int facemgr_query_bonjour(facemgr_t * facemgr, netdevice_t * netdevice)
DEBUG("sending event to bonjour interface");
/* Send an event to the interface (GET ?) */
+ // XXX error handling
return interface_on_event(bj, NULL);
}
#endif /* __linux__ */
@@ -508,8 +509,10 @@ int facemgr_query_android_utility(facemgr_t * facemgr, netdevice_t netdevice)
goto ERR_ND;
rc = interface_on_event(facemgr->au, facelet);
- if (rc < 0)
+ if (rc < 0) {
+ // XXX error handling
goto ERR_EVENT;
+ }
return 0;
@@ -957,7 +960,7 @@ int facemgr_assign_face_type(facemgr_t * facemgr, facelet_t * facelet)
netdevice_t netdevice = NETDEVICE_EMPTY;
int rc = facelet_get_netdevice(facelet, &netdevice);
if (rc < 0) {
- ERROR("[facemgr_facelet_satisfy_rules] Error retrieving netdevice from facelet");
+ ERROR("[facemgr_assign_face_type] Error retrieving netdevice from facelet");
return -1;
}
@@ -969,7 +972,7 @@ int facemgr_assign_face_type(facemgr_t * facemgr, facelet_t * facelet)
*/
rc = facelet_get_netdevice_type(facelet, &netdevice_type);
if (rc < 0) {
- ERROR("[facemgr_facelet_satisfy_rules] Error retrieving netdevice_type from facelet");
+ ERROR("[facemgr_assign_face_type] Error retrieving netdevice_type from facelet");
return -2;
}
#endif /* WITH_ANDROID_UTILITY */
@@ -991,6 +994,7 @@ int
facemgr_process_facelet(facemgr_t * facemgr, facelet_t * facelet)
{
int rc;
+ facelet_error_reason_t reason = FACELET_ERROR_REASON_INTERNAL_ERROR;
switch(facelet_get_status(facelet)) {
case FACELET_STATUS_UNCERTAIN:
@@ -1048,8 +1052,10 @@ facemgr_process_facelet(facemgr_t * facemgr, facelet_t * facelet)
case FACELET_STATUS_CREATE:
facelet_set_event(facelet, FACELET_EVENT_CREATE);
- if (interface_on_event(facemgr->hl, facelet) < 0) {
+ rc = interface_on_event(facemgr->hl, facelet);
+ if (rc < 0) {
ERROR("[facemgr_process_facelet] Failed to create face");
+ reason = -rc;
goto ERR;
}
@@ -1060,8 +1066,10 @@ facemgr_process_facelet(facemgr_t * facemgr, facelet_t * facelet)
case FACELET_STATUS_UPDATE:
facelet_set_event(facelet, FACELET_EVENT_UPDATE);
- if (interface_on_event(facemgr->hl, facelet) < 0) {
+ rc = interface_on_event(facemgr->hl, facelet);
+ if (rc < 0) {
ERROR("[facemgr_process_facelet] Failed to update face");
+ reason = -rc;
goto ERR;
}
@@ -1071,8 +1079,10 @@ facemgr_process_facelet(facemgr_t * facemgr, facelet_t * facelet)
case FACELET_STATUS_DELETE:
facelet_set_event(facelet, FACELET_EVENT_DELETE);
- if (interface_on_event(facemgr->hl, facelet) < 0) {
+ rc = interface_on_event(facemgr->hl, facelet);
+ if (rc < 0) {
ERROR("[facemgr_process_facelet] Failed to delete face");
+ reason = -rc;
goto ERR;
}
@@ -1102,11 +1112,11 @@ facemgr_process_facelet(facemgr_t * facemgr, facelet_t * facelet)
goto ERR;
}
- facelet_set_status_error(facelet, false);
+ facelet_unset_error(facelet);
return 0;
ERR:
- facelet_set_status_error(facelet, true);
+ facelet_set_error(facelet, reason);
return -1;
}
@@ -1122,11 +1132,12 @@ facemgr_reattempt_timeout(facemgr_t * facemgr, int fd, void * data)
int n = facelet_set_get_array(facemgr->facelet_cache, &facelet_array);
if (n < 0) {
ERROR("[facemgr_reattempt_timeout] Could not retrieve facelets in cache");
+ has_error = true;
} else {
for (unsigned i = 0; i < n; i++) {
facelet_t * facelet = facelet_array[i];
- if (!facelet_get_status_error(facelet))
+ if (!facelet_get_error(facelet))
continue;
char buf[MAXSZ_FACELET];
@@ -1137,7 +1148,7 @@ facemgr_reattempt_timeout(facemgr_t * facemgr, int fd, void * data)
has_error = true;
continue;
}
- facelet_set_status_error(facelet, false);
+ facelet_unset_error(facelet);
}
free(facelet_array);
}
@@ -1686,41 +1697,54 @@ facemgr_bootstrap(facemgr_t * facemgr)
DEBUG("Registering interfaces...");
rc = interface_register(&hicn_light_ops);
if (rc < 0) {
- ERROR("Could not register interfaces");
+ ERROR("[facemgr_bootstrap] Error registering hicn_light interface");
goto ERR_REGISTER;
}
#ifdef __APPLE__
rc = interface_register(&network_framework_ops);
- if (rc < 0)
+ if (rc < 0) {
+ ERROR("[facemgr_bootstrap] Error registering network_framework interface");
goto ERR_REGISTER;
+ }
#endif /* __APPLE__ */
#ifdef __linux__
rc = interface_register(&netlink_ops);
- if (rc < 0)
+ if (rc < 0) {
+ ERROR("[facemgr_bootstrap] Error registering netlink interface");
goto ERR_REGISTER;
+ }
+
rc = interface_register(&bonjour_ops);
- if (rc < 0)
+ if (rc < 0) {
+ ERROR("[facemgr_bootstrap] Error registering bonjour interface");
goto ERR_REGISTER;
+ }
#endif /* __linux__ */
#ifdef WITH_ANDROID_UTILITY
rc = interface_register(&android_utility_ops);
- if (rc < 0)
+ if (rc < 0) {
+ ERROR("[facemgr_bootstrap] Error registering android_utility interface");
goto ERR_REGISTER;
+ }
#endif /* WITH_ANDROID_UTILITY */
#ifdef WITH_EXAMPLE_DUMMY
rc = interface_register(&dummy_ops);
- if (rc < 0)
+ if (rc < 0) {
+ ERROR("[facemgr_bootstrap] Error registering dummy interface");
goto ERR_REGISTER;
+ }
#endif
#ifdef WITH_EXAMPLE_UPDOWN
rc = interface_register(&updown_ops);
- if (rc < 0)
+ if (rc < 0) {
+ ERROR("[facemgr_bootstrap] Error registering updown interface");
goto ERR_REGISTER;
+ }
#endif
rc = facemgr_create_interface(facemgr, "hl", "hicn_light", NULL, &facemgr->hl);
@@ -1778,7 +1802,6 @@ facemgr_bootstrap(facemgr_t * facemgr)
return 0;
- /* FIXME facemgr_delete_interface */
#ifdef WITH_EXAMPLE_UPDOWN
facemgr_delete_interface(facemgr, facemgr->updown);
ERR_UPDOWN_CREATE:
diff --git a/ctrl/facemgr/src/facelet.c b/ctrl/facemgr/src/facelet.c
index 7a34b18c8..308302e22 100644
--- a/ctrl/facemgr/src/facelet.c
+++ b/ctrl/facemgr/src/facelet.c
@@ -47,15 +47,19 @@ const char * face_type_encap_str[] = {
#define FACEMGR_FACE_TYPE_STR(x) \
face_type_layer_str[x.layer], face_type_encap_str[x.encap]
-
const char * facelet_status_str[] = {
#define _(x) [FACELET_STATUS_ ## x] = STRINGIZE(x),
foreach_facelet_status
#undef _
};
-/* Facelet attribute status */
+const char * facelet_error_reason_str[] = {
+#define _(x) [FACELET_ERROR_REASON_ ## x] = STRINGIZE(x),
+ foreach_facelet_error_reason
+#undef _
+};
+/* Facelet attribute status */
const char * facelet_attr_status_str[] = {
#define _(x, str) [FACELET_ATTR_STATUS_ ## x] = STRINGIZE(x),
@@ -85,7 +89,7 @@ struct facelet_s {
facelet_status_t status;
- bool status_error;
+ int error;
facelet_event_t event;
@@ -123,7 +127,7 @@ facelet_create()
facelet->face_type_status = FACELET_ATTR_STATUS_UNSET;
facelet->status = FACELET_STATUS_UNDEFINED;
- facelet->status_error = false;
+ facelet->error = 0;
facelet->bj_done = false;
facelet->au_done = false;
@@ -330,7 +334,7 @@ facelet_create_from_face(face_t * face)
/* Status */
facelet->status = FACELET_STATUS_CLEAN;
- facelet->status_error = false;
+ facelet->error = 0;
/* TODO Consistency check between face type and found attributes */
if (facelet_validate_face(facelet) < 0)
@@ -852,15 +856,35 @@ facelet_set_status(facelet_t * facelet, facelet_status_t status)
}
void
-facelet_set_status_error(facelet_t * facelet, bool value)
+facelet_set_error(facelet_t * facelet, facelet_error_reason_t reason)
+{
+ facelet->error++;
+ switch(reason) {
+ case FACELET_ERROR_REASON_UNSPECIFIED_ERROR:
+ case FACELET_ERROR_REASON_INTERNAL_ERROR:
+ case FACELET_ERROR_REASON_PERMISSION_DENIED:
+ if (facelet->error >= FACELET_MAX_ERRORS)
+ facelet_set_status(facelet, FACELET_STATUS_IGNORED);
+ break;
+ case FACELET_ERROR_REASON_FORWARDER_OFFLINE:
+ break;
+ case FACELET_ERROR_REASON_UNDEFINED:
+ case FACELET_ERROR_REASON_N:
+ ERROR("facelet_set_error] Unexpected error reason");
+ break;
+ }
+}
+
+void
+facelet_unset_error(facelet_t * facelet)
{
- facelet->status_error = value;
+ facelet->error = 0;
}
bool
-facelet_get_status_error(const facelet_t * facelet)
+facelet_get_error(const facelet_t * facelet)
{
- return facelet->status_error;
+ return facelet->error;
}
void
@@ -934,7 +958,7 @@ facelet_snprintf(char * s, size_t size, const facelet_t * facelet)
/* Header + key attributes (netdevice + family) */
rc = snprintf(cur, s + size - cur, "<Facelet %s %s (%s)",
facelet_status_str[facelet->status],
- facelet_get_status_error(facelet) ? "/!\\" : "",
+ facelet_get_error(facelet) ? "/!\\" : "",
(facelet->family == AF_INET) ? "AF_INET" :
(facelet->family == AF_INET6) ? "AF_INET6" :
(facelet->family == AF_UNSPEC) ? "AF_UNSPEC" :
@@ -1298,7 +1322,7 @@ int facelet_snprintf_json(char * s, size_t size, const facelet_t * facelet, int
/* Status error */
rc = snprintf(cur, s + size - cur, "%*s%s: \"%s\"\n", 4 * (indent+1), "",
"\"error\"",
- facelet_get_status_error(facelet) ? "true" : "false");
+ facelet_get_error(facelet) ? "true" : "false");
if (rc < 0)
return rc;
cur += rc;
diff --git a/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c b/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c
index 945b60af2..76edfec10 100644
--- a/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c
+++ b/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c
@@ -238,11 +238,13 @@ int hl_on_event(interface_t * interface, const facelet_t * facelet)
*/
if (facelet_get_face(facelet, &face) < 0) {
ERROR("Could not retrieve face from facelet");
+ ret = -FACELET_ERROR_REASON_INTERNAL_ERROR;
goto ERR_FACE;
}
if (!data->s) {
/* We are not connected to the forwarder */
+ ret = -FACELET_ERROR_REASON_FORWARDER_OFFLINE;
goto ERR;
}
@@ -260,6 +262,7 @@ int hl_on_event(interface_t * interface, const facelet_t * facelet)
rc = hc_face_create(data->s, &hc_face);
if (rc < 0) {
ERROR("Failed to create face\n");
+ ret = -FACELET_ERROR_REASON_UNSPECIFIED_ERROR;
goto ERR;
}
INFO("Created face id=%d", hc_face.id);
@@ -268,6 +271,7 @@ int hl_on_event(interface_t * interface, const facelet_t * facelet)
int n = facelet_get_route_array(facelet, &route_array);
if (n < 0) {
ERROR("Failed to create default hICN/IPv4 route");
+ ret = -FACELET_ERROR_REASON_UNSPECIFIED_ERROR;
goto ERR;
}
if (n == 0) {
@@ -326,7 +330,6 @@ int hl_on_event(interface_t * interface, const facelet_t * facelet)
continue;
}
}
-
}
break;
@@ -338,6 +341,7 @@ int hl_on_event(interface_t * interface, const facelet_t * facelet)
rc = hc_face_delete(data->s, &hc_face);
if (rc < 0) {
ERROR("Failed to delete face\n");
+ ret = -FACELET_ERROR_REASON_UNSPECIFIED_ERROR;
goto ERR;
}
break;
@@ -351,10 +355,12 @@ int hl_on_event(interface_t * interface, const facelet_t * facelet)
rc = hc_face_get(data->s, &hc_face, &face_found);
if (rc < 0) {
ERROR("Failed to find face\n");
+ ret = -FACELET_ERROR_REASON_INTERNAL_ERROR;
goto ERR;
}
if (!face_found) {
ERROR("Face to update has not been found");
+ ret = -FACELET_ERROR_REASON_UNSPECIFIED_ERROR;
goto ERR;
}
char conn_id_or_name[SYMBOLIC_NAME_LEN];
@@ -364,11 +370,13 @@ int hl_on_event(interface_t * interface, const facelet_t * facelet)
face_state_t admin_state;
if (facelet_get_admin_state(facelet, &admin_state) < 0) {
ERROR("Failed to retrieve facelet admin state");
+ ret = -FACELET_ERROR_REASON_INTERNAL_ERROR;
goto ERR;
}
if (hc_connection_set_admin_state(data->s, conn_id_or_name, admin_state) < 0) {
ERROR("Failed to update admin state");
+ ret = -FACELET_ERROR_REASON_UNSPECIFIED_ERROR;
goto ERR;
}
INFO("Admin state updated");
@@ -378,16 +386,14 @@ int hl_on_event(interface_t * interface, const facelet_t * facelet)
default:
ERROR("Unknown event %s\n", facelet_event_str[facelet_get_event(facelet)]);
/* Unsupported events */
+ ret = -FACELET_ERROR_REASON_INTERNAL_ERROR;
goto ERR;
}
- face_free(face);
- return ret;
-
ERR:
face_free(face);
ERR_FACE:
- return -1;
+ return ret;
}
int hl_callback(interface_t * interface, int fd, void * unused)