aboutsummaryrefslogtreecommitdiffstats
path: root/ctrl/facemgr/src/api.c
diff options
context:
space:
mode:
Diffstat (limited to 'ctrl/facemgr/src/api.c')
-rw-r--r--ctrl/facemgr/src/api.c326
1 files changed, 241 insertions, 85 deletions
diff --git a/ctrl/facemgr/src/api.c b/ctrl/facemgr/src/api.c
index 18a25d6a1..d9bba43a9 100644
--- a/ctrl/facemgr/src/api.c
+++ b/ctrl/facemgr/src/api.c
@@ -566,7 +566,7 @@ facelet_cache_lookup(const facelet_set_t * facelet_cache, facelet_t * facelet,
#if 0
char facelet_s[MAXSZ_FACELET];
facelet_snprintf(facelet_s, MAXSZ_FACELET, facelet_array[i]);
- printf("cache entry #%d/%di = %s\n", i+1, n, facelet_s);
+ DEBUG("cache entry #%d/%di = %s", i+1, n, facelet_s);
#endif
if (!facelet_match(facelet_array[i], facelet)) {
continue;
@@ -955,6 +955,7 @@ facemgr_complement_facelet(facemgr_t * facemgr, facelet_t * facelet)
int facemgr_assign_face_type(facemgr_t * facemgr, facelet_t * facelet)
{
+ DEBUG("[facemgr_assign_face_type]");
/* As key, netdevice and family should always be present */
netdevice_t netdevice = NETDEVICE_EMPTY;
int rc = facelet_get_netdevice(facelet, &netdevice);
@@ -980,6 +981,7 @@ int facemgr_assign_face_type(facemgr_t * facemgr, facelet_t * facelet)
if (facemgr_cfg_get_face_type(facemgr->cfg, &netdevice, netdevice_type, &face_type) < 0)
return rc;
facelet_set_face_type(facelet, face_type);
+ DEBUG("[facemgr_assign_face_type] %s", FACEMGR_FACE_TYPE_STR(face_type));
return 0;
}
@@ -1085,6 +1087,14 @@ facemgr_process_facelet(facemgr_t * facemgr, facelet_t * facelet)
goto ERR;
}
+ if (facelet_set_remove(facemgr->facelet_cache, facelet, NULL) < 0) {
+ ERROR("[facemgr_process_facelet] Could not remove deleted facelet from cache");
+ goto ERR;
+ }
+ facelet_free(facelet);
+ goto END;
+
+#if 0
/* This works assuming the call to hicn-light is blocking */
DEBUG("[facemgr_process_facelet] Cleaning cached data");
facelet_unset_local_addr(facelet);
@@ -1099,10 +1109,12 @@ facemgr_process_facelet(facemgr_t * facemgr, facelet_t * facelet)
#endif /* WITH_ANDROID_UTILITY */
facelet_set_status(facelet, FACELET_STATUS_DELETED);
+#endif
break;
case FACELET_STATUS_CLEAN:
case FACELET_STATUS_IGNORED:
+ case FACELET_STATUS_DOWN:
case FACELET_STATUS_DELETED:
/* Nothing to do */
break;
@@ -1114,6 +1126,7 @@ facemgr_process_facelet(facemgr_t * facemgr, facelet_t * facelet)
}
facelet_unset_error(facelet);
+END:
return 0;
ERR:
@@ -1219,6 +1232,7 @@ facemgr_process_facelet_create(facemgr_t * facemgr, facelet_t * facelet)
*/
break;
+ case FACELET_STATUS_DOWN:
case FACELET_STATUS_DELETED:
/*
* Unless rules have changed, we only need to recover
@@ -1285,6 +1299,7 @@ facemgr_consider_static_facelet(facemgr_t * facemgr, facelet_t * facelet)
*/
facelet_t * static_facelet = facelet_dup(facelet);
+ facelet_set_event(static_facelet, FACELET_EVENT_CREATE);
facelet_unset_netdevice(static_facelet);
facelet_unset_netdevice_type(static_facelet);
facelet_unset_local_addr(static_facelet);
@@ -1339,6 +1354,43 @@ facemgr_process_facelet_get(facemgr_t * facemgr, facelet_t * facelet)
return -2;
facelet_set_status(facelet, FACELET_STATUS_CLEAN);
+ /* Process untagged faces */
+ netdevice_type_t netdevice_type;
+ if (facelet_get_netdevice_type(facelet, &netdevice_type) < 0) {
+ facelet_set_netdevice_type(facelet, facemgr_get_netdevice_type(facemgr, netdevice.name));
+ if (facelet_get_netdevice_type(facelet, &netdevice_type) < 0) {
+ /* Inspect local address */
+ int family;
+ ip_address_t local;
+ if (facelet_get_family(facelet, &family) < 0) {
+ ERROR("[facemgr_process_facelet_get] Error getting facelet family");
+ return -1;
+ }
+ if (facelet_get_local_addr(facelet, &local) < 0) {
+ ERROR("[facemgr_process_facelet_get] Error getting facelet local address");
+ return -1;
+ }
+ switch(family) {
+ case AF_INET:
+ if (ip_address_cmp(&local, &IPV4_LOOPBACK, family) == 0) {
+ facelet_set_netdevice_type(facelet, NETDEVICE_TYPE_LOOPBACK);
+ } else {
+ return -2;
+ }
+ break;
+ case AF_INET6:
+ if (ip_address_cmp(&local, &IPV6_LOOPBACK, family) == 0) {
+ facelet_set_netdevice_type(facelet, NETDEVICE_TYPE_LOOPBACK);
+ } else {
+ return -2;
+ }
+ break;
+ default:
+ return -2;
+ }
+ }
+ }
+
int n = facemgr_consider_static_facelet(facemgr, facelet);
if (n < 0) {
ERROR("[facemgr_process_facelet_get] Could not add facelet to static array");
@@ -1354,7 +1406,20 @@ facemgr_process_facelet_get(facemgr_t * facemgr, facelet_t * facelet)
char facelet_s[MAXSZ_FACELET];
facelet_snprintf(facelet_s, MAXSZ_FACELET, facelet);
- return facelet_set_add(facemgr->facelet_cache, facelet);
+ if (facelet_set_add(facemgr->facelet_cache, facelet) < 0) {
+ ERROR("[facemgr_process_facelet_get] Error adding received facelet to cache");
+ return -1;
+ }
+
+ /* Proceed to the update is the facelet status is not clean */
+ if (facelet_get_status(facelet) != FACELET_STATUS_CLEAN) {
+ if (facemgr_process_facelet(facemgr, facelet) < 0) {
+ ERROR("[facemgr_process_facelet_get] Error processing facelet");
+ return -1;
+ }
+ }
+
+ return 0;
}
/**
@@ -1377,6 +1442,7 @@ facemgr_process_facelet_update(facemgr_t * facemgr, facelet_t * facelet)
case FACELET_STATUS_CLEAN:
facelet_set_status(facelet, FACELET_STATUS_UPDATE);
break;
+ case FACELET_STATUS_DOWN:
case FACELET_STATUS_DELETE:
case FACELET_STATUS_DELETED:
case FACELET_STATUS_IGNORED:
@@ -1410,7 +1476,16 @@ facemgr_process_facelet_delete(facemgr_t * facemgr, facelet_t * facelet)
switch(facelet_get_status(facelet)) {
case FACELET_STATUS_UNCERTAIN:
case FACELET_STATUS_INCOMPLETE:
- case FACELET_STATUS_CREATE:
+ case FACELET_STATUS_IGNORED:
+ case FACELET_STATUS_DOWN:
+ if (facelet_set_remove(facemgr->facelet_cache, facelet, NULL) < 0) {
+ ERROR("[facemgr_process_facelet] Could not remove deleted facelet from cache");
+ return -1;
+ }
+
+ facelet_free(facelet);
+ return 0;
+#if 0
facelet_unset_local_addr(facelet);
facelet_unset_local_port(facelet);
facelet_unset_remote_addr(facelet);
@@ -1420,13 +1495,14 @@ facemgr_process_facelet_delete(facemgr_t * facemgr, facelet_t * facelet)
facelet_unset_au_done(facelet);
#endif /* WITH_ANDROID_UTILITY */
facelet_set_status(facelet, FACELET_STATUS_DELETED);
+#endif
break;
+ case FACELET_STATUS_CREATE:
case FACELET_STATUS_UPDATE:
case FACELET_STATUS_CLEAN:
facelet_set_status(facelet, FACELET_STATUS_DELETE);
break;
case FACELET_STATUS_DELETE:
- case FACELET_STATUS_IGNORED:
case FACELET_STATUS_DELETED:
/* Nothing to do */
DEBUG("%s\n", facelet_status_str[facelet_get_status(facelet)]);
@@ -1445,11 +1521,12 @@ facemgr_process_facelet_delete(facemgr_t * facemgr, facelet_t * facelet)
return 0;
}
+#if 0
int facemgr_process_facelet_first_time(facemgr_t * facemgr, facelet_t * facelet)
{
- facelet_set_status(facelet, FACELET_STATUS_UNCERTAIN);
-
assert(facelet);
+
+ facelet_set_status(facelet, FACELET_STATUS_UNCERTAIN);
char facelet_s[MAXSZ_FACELET];
facelet_snprintf(facelet_s, MAXSZ_FACELET, facelet);
if (facelet_set_add(facemgr->facelet_cache, facelet) < 0) {
@@ -1471,6 +1548,89 @@ ERR_CREATE:
ERR_CACHE:
return -1;
}
+#endif
+
+int facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet);
+
+int
+facemgr_process_facelet_create_no_family(facemgr_t * facemgr, facelet_t * facelet)
+{
+
+ DEBUG("[facemgr_process_facelet_create_no_family] Default v4");
+ /* Create default v4 and v6 facelets */
+ facelet_t * facelet_v4 = facelet_dup(facelet);
+ if (!facelet_v4) {
+ ERROR("[facemgr_process_facelet_create_no_family] Error allocating default IPv4 face");
+ } else {
+ facelet_set_family(facelet_v4, AF_INET);
+ facelet_set_status(facelet_v4, FACELET_STATUS_CLEAN);
+ if (facemgr_on_event(facemgr, facelet_v4) < 0) {
+ ERROR("[facemgr_process_facelet_create_no_family] Error creating default IPv4 face");
+ facelet_free(facelet_v4);
+ }
+ }
+
+ DEBUG("[facemgr_process_facelet_create_no_family] Default v6");
+ facelet_t * facelet_v6 = facelet_dup(facelet);
+ if (!facelet_v6) {
+ ERROR("[facemgr_process_facelet_create_no_family] Error allocating default IPv6 face");
+ } else {
+ facelet_set_family(facelet_v6, AF_INET6);
+ facelet_set_status(facelet_v6, FACELET_STATUS_CLEAN);
+ if (facemgr_on_event(facemgr, facelet_v6) < 0) {
+ ERROR("[facemgr_process_facelet_create_no_family] Error creating default IPv6 face");
+ facelet_free(facelet_v6);
+ }
+ }
+
+ /* Create additional connections
+ *
+ * This is where we spawn multiple facelets based on the
+ * configured "static routes" in addition to the default
+ * routes managed by the face manager.
+ */
+ DEBUG("[facemgr_process_facelet_create_no_family] Loop static");
+ for (unsigned i = 0; i < facelet_array_len(facemgr->static_facelets); i++) {
+ facelet_t * static_facelet;
+ if (facelet_array_get_index(facemgr->static_facelets, i, &static_facelet) < 0) {
+ ERROR("[facemgr_process_facelet_create_no_family] Error getting static facelet");
+ continue;
+ }
+
+ /*
+ * We don't enforce any present or absent fields. A match
+ * operation will be performed deciding whether to create
+ * the facelet (if it bring additional information to the
+ * ingress one) or not.
+ */
+ /* We try to apply static_facelet over facelet */
+ if (!facelet_match(facelet, static_facelet)) {
+ continue;
+ }
+
+ facelet_t * facelet_new = facelet_dup(facelet);
+ if (!facelet_new) {
+ ERROR("[facemgr_process_facelet_create_no_family] Error allocating static facelet");
+ continue;
+ } else {
+ if (facelet_merge(facelet_new, static_facelet) < 0) {
+ ERROR("[facemgr_process_facelet_create_no_family] Error merging facelets");
+ facelet_free(facelet_new);
+ continue;
+ }
+ /* The id must be different than 0 */
+ facelet_set_id(facelet_new, ++facemgr->cur_static_id);
+ facelet_set_status(facelet_new, FACELET_STATUS_CLEAN);
+
+ if (facemgr_on_event(facemgr, facelet_new) < 0) {
+ ERROR("[facemgr_process_facelet_create_no_family] Error creating default IPv6 face");
+ facelet_free(facelet_new);
+ }
+ }
+ }
+
+ return 0;
+}
/**
* \brief Process incoming events from interfaces
@@ -1489,7 +1649,9 @@ facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in)
assert(facelet_in);
/* Update Netdevice type */
- if (facelet_has_netdevice(facelet_in) && (!facelet_has_netdevice_type(facelet_in))) {
+ if ((facelet_get_event(facelet_in) != FACELET_EVENT_GET) &&
+ facelet_has_netdevice(facelet_in) &&
+ (!facelet_has_netdevice_type(facelet_in))) {
netdevice_t netdevice = NETDEVICE_EMPTY;
rc = facelet_get_netdevice(facelet_in, &netdevice);
@@ -1505,6 +1667,7 @@ facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in)
facelet_t ** cached_facelets = NULL;
assert(facelet_in);
+
int n = facelet_cache_lookup(facemgr->facelet_cache, facelet_in, &cached_facelets);
if (n < 0) {
ERROR("[facemgr_on_event] Error during cache lookup");
@@ -1524,85 +1687,29 @@ facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in)
* assignment
*/
DEBUG("[facemgr_on_event] CREATE NEW %s", facelet_s);
- assert(!facelet_has_family(facelet_in));
-
- /* Create default v4 and v6 facelets */
- facelet_t * facelet_v4 = facelet_dup(facelet_in);
- if (!facelet_v4) {
- ERROR("[facemgr_on_event] Error allocating default IPv4 face");
- facelet_free(facelet_v4);
- } else {
- facelet_set_family(facelet_v4, AF_INET);
- facelet_set_status(facelet_v4, FACELET_STATUS_CLEAN);
- if (facemgr_process_facelet_first_time(facemgr, facelet_v4) < 0) {
- ERROR("[facemgr_on_event] Error creating default IPv4 face");
- facelet_free(facelet_v4);
- }
- }
-
- facelet_t * facelet_v6 = facelet_dup(facelet_in);
- if (!facelet_v6) {
- ERROR("[facemgr_on_event] Error allocating default IPv6 face");
- facelet_free(facelet_v4);
- } else {
- facelet_set_family(facelet_v6, AF_INET6);
- facelet_set_status(facelet_v6, FACELET_STATUS_CLEAN);
- if (facemgr_process_facelet_first_time(facemgr, facelet_v6) < 0) {
- ERROR("[facemgr_on_event] Error creating default IPv6 face");
- facelet_free(facelet_v6);
+ if (!facelet_has_family(facelet_in)) {
+ facemgr_assign_face_type(facemgr, facelet_in);
+ if (facemgr_process_facelet_create_no_family(facemgr, facelet_in) < 0) {
+ ERROR("[facemgr_on_event] Error processing new interface event");
+ goto ERR;
}
+ goto DUMP_CACHE;
}
- /* Create additional connections
- *
- * This is where we spawn multiple facelets based on the
- * configured "static routes" in addition to the default
- * routes managed by the face manager.
- */
- for (unsigned i = 0; i < facelet_array_len(facemgr->static_facelets); i++) {
- facelet_t * static_facelet;
- if (facelet_array_get_index(facemgr->static_facelets, i, &static_facelet) < 0) {
- ERROR("[facemgr_on_event] Error getting static facelet");
- goto ERR;
- }
+ facelet_set_status(facelet_in, FACELET_STATUS_UNCERTAIN);
- /*
- * We don't enforce any present or absent fields. A match
- * operation will be performed deciding whether to create
- * the facelet (if it bring additional information to the
- * ingress one) or not.
- */
- /* We try to apply static_facelet over facelet_in */
- if (!facelet_match(facelet_in, static_facelet)) {
- continue;
- }
+ if (facelet_set_add(facemgr->facelet_cache, facelet_in) < 0) {
+ ERROR("[facemgr_on_event] Error adding facelet to cache");
+ goto ERR;
+ }
- facelet_t * facelet_new = facelet_dup(facelet_in);
- if (!facelet_new) {
- ERROR("[facemgr_on_event] Error allocating static facelet");
- goto ERR;
- } else {
- if (facelet_merge(facelet_new, static_facelet) < 0) {
- ERROR("[facemgr_on_event] Error merging facelets");
- continue;
- }
- /* The id must be different than 0 */
- facelet_set_id(facelet_new, ++facemgr->cur_static_id);
- facelet_set_status(facelet_new, FACELET_STATUS_CLEAN);
-
- char buf[MAXSZ_FACELET];
- facelet_snprintf(buf, MAXSZ_FACELET, facelet_new);
- if (facemgr_process_facelet_first_time(facemgr, facelet_new) < 0) {
- ERROR("[facemgr_on_event] Error creating default IPv6 face");
- facelet_free(facelet_v6);
- }
- }
+ if (facemgr_process_facelet_create(facemgr, facelet_in) < 0) {
+ ERROR("[facemgr_on_event] Error processing facelet CREATE event");
+ ret = -1;
}
- /*
- * We always remove the original facelet here, no need to
- * preserve it
- */
+ remove_facelet = false;
+
break;
}
@@ -1632,6 +1739,11 @@ facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in)
ERROR("[facemgr_on_event] Unexpected DELETE... face does not exist");
goto ERR;
+ case FACELET_EVENT_SET_UP:
+ case FACELET_EVENT_SET_DOWN:
+ ERROR("[facemgr_on_event] Unexpected event on a face that does not exist");
+ goto ERR;
+
case FACELET_EVENT_UNDEFINED:
case FACELET_EVENT_N:
ERROR("[facemgr_on_event] Unexpected UNDEFINED event.");
@@ -1653,13 +1765,27 @@ facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in)
*/
facelet_t * facelet = cached_facelets[i];
- char facelet_s[MAXSZ_FACELET];
- facelet_snprintf(facelet_s, MAXSZ_FACELET, facelet);
+ char facelet_old_s[MAXSZ_FACELET];
+ facelet_snprintf(facelet_old_s, MAXSZ_FACELET, facelet);
//DEBUG("Facelet from cache #%d %s", i, facelet_s);
switch(facelet_get_event(facelet_in)) {
case FACELET_EVENT_CREATE:
+ /*
+ * This can occur for a facelet already in cache but that has
+ * been previously deleted... we need to be able to consider
+ * static facelets in this situation too...
+ */
DEBUG("[facemgr_on_event] CREATE EXISTING %s", facelet_s);
+
+ if (!facelet_has_family(facelet_in)) {
+ if (facemgr_process_facelet_create_no_family(facemgr, facelet_in) < 0) {
+ ERROR("[facemgr_on_event] Error processing new interface event");
+ goto ERR;
+ }
+ goto DUMP_CACHE;
+ }
+
// This case will occur when we try to re-create existing faces,
// eg. in the situation of a forwarder restarting.
// likely this occurs when the interface receives a (potentially new) address
@@ -1680,13 +1806,15 @@ facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in)
* This happens due to polling of the forwarder (or when it
* restarts)
*/
- DEBUG("[facemgr_on_event] GET EXISTING %s", facelet_s);
+ DEBUG("[facemgr_on_event] GET EXISTING %s", facelet_old_s);
+ DEBUG(" WITH %s", facelet_s);
//ERROR("[facemgr_on_event] GET event for a face that already exists...");
dump = false;
continue;
case FACELET_EVENT_UPDATE:
- DEBUG("[facemgr_on_event] UPDATE EXISTING %s", facelet_s);
+ DEBUG("[facemgr_on_event] UPDATE EXISTING %s", facelet_old_s);
+ DEBUG(" WITH %s", facelet_s);
if (facelet_merge(facelet, facelet_in) < 0) {
ERROR("[facemgr_on_event] Error merging facelets");
continue;
@@ -1698,7 +1826,8 @@ facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in)
continue;
case FACELET_EVENT_DELETE:
- DEBUG("[facemgr_on_event] DELETE EXISTING %s", facelet_s);
+ DEBUG("[facemgr_on_event] DELETE EXISTING %s", facelet_old_s);
+ DEBUG(" WITH %s", facelet_s);
if (facelet_merge(facelet, facelet_in) < 0) {
ERROR("[facemgr_on_event] Error merging facelets");
continue;
@@ -1709,6 +1838,31 @@ facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in)
}
continue;
+ case FACELET_EVENT_SET_UP:
+ ERROR("[facemgr_on_event] Not implemented\n");
+ ret = -1;
+ continue;
+
+ case FACELET_EVENT_SET_DOWN:
+ DEBUG("[facemgr_on_event] SET DOWN EXISTING %s", facelet_old_s);
+ DEBUG(" WITH %s", facelet_s);
+ /* We don't even need to merge */
+ if (facelet_merge(facelet, facelet_in) < 0) {
+ ERROR("[facemgr_on_event] Error merging facelets");
+ continue;
+ }
+ if (facemgr_process_facelet_delete(facemgr, facelet) < 0) {
+ ERROR("[facemgr_on_event] Error processing facelet DELETE event");
+ continue;
+ }
+ /*
+ if (facelet_set_remove(facemgr->facelet_cache, facelet, NULL) < 0) {
+ ERROR("[facemgr_process_facelet] Could not remove down facelet from cache");
+ goto ERR;
+ }
+ */
+ continue;
+
case FACELET_EVENT_UNDEFINED:
case FACELET_EVENT_N:
ERROR("[facemgr_on_event] Unexpected UNDEFINED event.");
@@ -1739,8 +1893,10 @@ DUMP_CACHE:
if (remove_facelet)
facelet_free(facelet_in);
- if (ret == -1)
+ if (ret == -1) {
+ INFO("Error... starting reattempts");
facemgr_start_reattempts(facemgr);
+ }
return ret;
}