aboutsummaryrefslogtreecommitdiffstats
path: root/ctrl/facemgr/src/facelet.c
diff options
context:
space:
mode:
Diffstat (limited to 'ctrl/facemgr/src/facelet.c')
-rw-r--r--ctrl/facemgr/src/facelet.c121
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;