diff options
Diffstat (limited to 'ctrl/facemgr/src/facelet.c')
-rw-r--r-- | ctrl/facemgr/src/facelet.c | 121 |
1 files changed, 106 insertions, 15 deletions
diff --git a/ctrl/facemgr/src/facelet.c b/ctrl/facemgr/src/facelet.c index 7a34b18c8..929005f57 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; @@ -120,10 +124,13 @@ facelet_create() facelet->remote_port_status = FACELET_ATTR_STATUS_UNSET; facelet->admin_state_status = FACELET_ATTR_STATUS_UNSET; facelet->state_status = FACELET_ATTR_STATUS_UNSET; +#ifdef WITH_POLICY + facelet->priority_status = FACELET_ATTR_STATUS_UNSET; +#endif /* WITH_POLICY */ 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; @@ -229,7 +236,8 @@ facelet_create_from_face(face_t * face) /* Attribute : netdevice */ /* NOTE index is not set */ if (IS_VALID_NETDEVICE(face->netdevice)) { - facelet->netdevice = face->netdevice; + /* /!\ A face has only the netdevice name */ + netdevice_set_name(&facelet->netdevice, face->netdevice.name); facelet->netdevice_status = FACELET_ATTR_STATUS_CLEAN; } else { facelet->netdevice_status = FACELET_ATTR_STATUS_UNSET; @@ -240,7 +248,7 @@ facelet_create_from_face(face_t * face) if (facelet->netdevice_type != NETDEVICE_TYPE_UNDEFINED) { facelet->netdevice_type_status = FACELET_ATTR_STATUS_CLEAN; } else { - facelet->netdevice = NETDEVICE_EMPTY; + facelet->netdevice_type = NETDEVICE_TYPE_UNDEFINED; facelet->netdevice_type_status = FACELET_ATTR_STATUS_UNSET; } @@ -307,6 +315,16 @@ facelet_create_from_face(face_t * face) facelet->state_status = FACELET_ATTR_STATUS_UNSET; } +#ifdef WITH_POLICY + /* Attribute : priority */ + if (face->priority > 0) { + facelet->priority = face->priority; + facelet->priority_status = FACELET_ATTR_STATUS_CLEAN; + } else { + facelet->priority_status = FACELET_ATTR_STATUS_UNSET; + } +#endif /* WITH_POLICY */ + /* Attribute : face_type */ if ((face->type != FACE_TYPE_UNDEFINED) && (face->type != FACE_TYPE_N)) { switch(face->type) { @@ -330,7 +348,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) @@ -407,13 +425,32 @@ facelet_dup(const facelet_t * current_facelet) } else { for (unsigned i = 0; i < n; i++) { hicn_route_t * route = route_array[i]; - route_set_add(facelet->routes, route); + hicn_route_t * new_route = hicn_route_dup(route); + if (!new_route) + goto ERR_ROUTE; + route_set_add(facelet->routes, new_route); } } free(route_array); return facelet; +ERR_ROUTE: + { + /* Free all routes */ + hicn_route_t ** new_route_array; + int n = route_set_get_array(facelet->routes, &new_route_array); + if (n < 0) { + ERROR("[facelet_free] Error getting route set associated to facelet"); + } else { + for (unsigned i = 0; i < n; i++) { + hicn_route_t * new_route = new_route_array[i]; + hicn_route_free(new_route); + } + } + free(route_array); + facelet_free(facelet); + } ERR_CREATE: return NULL; } @@ -489,7 +526,6 @@ do { } \ } while(0) -/* facelet_match is the incoming one */ bool facelet_equals(const facelet_t * facelet1, const facelet_t * facelet2) { @@ -786,6 +822,15 @@ facelet_get_face(const facelet_t * facelet, face_t ** pface) face->state = FACE_STATE_UP; } +#ifdef WITH_POLICY + /* Priority */ + if (facelet_has_priority(facelet)) { + if (facelet_get_priority(facelet, &face->priority) < 0) + goto ERR; + } else { + face->priority = 0; + } + /* Tags */ /* - based on netdevice type */ @@ -816,6 +861,7 @@ facelet_get_face(const facelet_t * facelet, face_t ** pface) } } face->tags = tags; +#endif /* WITH_POLICY */ *pface = face; @@ -852,15 +898,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->status_error = value; + 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->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 +1000,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" : @@ -1062,6 +1128,18 @@ facelet_snprintf(char * s, size_t size, const facelet_t * facelet) return cur - s; } +#ifdef WITH_POLICY + /* Priority */ + if (facelet_has_priority(facelet)) { + rc = snprintf(cur, s + size - cur, " priority=%d", facelet->priority); + if (rc < 0) + return rc; + cur += rc; + if (cur >= s + size) + return cur - s; + } +#endif /* WITH_POLICY */ + /* Face type */ if (facelet_has_face_type(facelet)) { rc = snprintf(cur, s + size - cur, " face_type=LAYER%s/%s", @@ -1284,6 +1362,19 @@ int facelet_snprintf_json(char * s, size_t size, const facelet_t * facelet, int return cur - s; } +#ifdef WITH_POLICY + /* Priority */ + if (facelet_has_priority(facelet)) { + rc = snprintf(cur, s + size - cur, "%*s%s: %d,\n", 4 * (indent+1), "", + "\"priority\"", facelet->priority); + if (rc < 0) + return rc; + cur += rc; + if (cur >= s + size) + return cur - s; + } +#endif /* WITH_POLICY */ + if (facelet_has_face_type(facelet)) { rc = snprintf(cur, s + size - cur, "%*s%s: \"LAYER%s/%s\",\n", 4 * (indent+1), "", "\"face_type\"", @@ -1298,7 +1389,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; |