From a2efba68e8fc25459ee524e31fc7228ee62d89ce Mon Sep 17 00:00:00 2001 From: Jordan Augé Date: Tue, 5 Nov 2019 12:56:37 +0100 Subject: [HICN-378] Add a maximum number of reattempts in face manager before entering face ignore mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Id6f8cc958d3c50027475d72d80eed6b65ac0996b Signed-off-by: Jordan Augé --- ctrl/facemgr/includes/hicn/facemgr/facelet.h | 24 ++++++++- ctrl/facemgr/src/api.c | 59 +++++++++++++++------- ctrl/facemgr/src/facelet.c | 46 +++++++++++++---- .../facemgr/src/interfaces/hicn_light/hicn_light.c | 16 ++++-- 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, "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) -- cgit 1.2.3-korg