summaryrefslogtreecommitdiffstats
path: root/ctrl/facemgr/src
diff options
context:
space:
mode:
authorJordan Augé <jordan.auge+fdio@cisco.com>2019-11-17 09:53:22 +0000
committerGerrit Code Review <gerrit@fd.io>2019-11-17 09:53:22 +0000
commit2dcc25795fab0100ce33852f08d77a5fd90d8f14 (patch)
treef133b4e05dd4f67588d65d0521349f14f2d38220 /ctrl/facemgr/src
parenta2efba68e8fc25459ee524e31fc7228ee62d89ce (diff)
parent45bc09ae553e7ac5bf6cd7ab2e77e7f6d0877596 (diff)
Merge "[HICN-395] Static face/route maintainance though face manager"
Diffstat (limited to 'ctrl/facemgr/src')
-rw-r--r--ctrl/facemgr/src/api.c204
-rw-r--r--ctrl/facemgr/src/facelet.c27
-rw-r--r--ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c218
3 files changed, 381 insertions, 68 deletions
diff --git a/ctrl/facemgr/src/api.c b/ctrl/facemgr/src/api.c
index 86d6e40b6..dfb23db3b 100644
--- a/ctrl/facemgr/src/api.c
+++ b/ctrl/facemgr/src/api.c
@@ -160,6 +160,8 @@ struct facemgr_s {
interface_t * updown;
#endif
int timer_fd; /* Timer used for reattempts */
+
+ int cur_static_id; /* Used to distinguish static faces (pre-incremented) */
};
int
@@ -198,6 +200,7 @@ facemgr_initialize(facemgr_t * facemgr)
}
facemgr->timer_fd = 0;
+ facemgr->cur_static_id = 0;
return 0;
@@ -538,6 +541,9 @@ int
facelet_cache_lookup(const facelet_set_t * facelet_cache, facelet_t * facelet,
facelet_t ***cached_facelets)
{
+ assert(facelet);
+ if (!facelet_has_family(facelet))
+ return 0;
#if 0 // key is no more sufficient now that we support multiple faces per interface
/*
* If the facelet is uniquely identified by its key, it is used to perform
@@ -570,6 +576,11 @@ facelet_cache_lookup(const facelet_set_t * facelet_cache, facelet_t * facelet,
int num_match = 0;
for (unsigned i = 0; i < n; i++) {
+#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);
+#endif
if (!facelet_match(facelet_array[i], facelet)) {
continue;
}
@@ -684,6 +695,7 @@ facemgr_complement_facelet_au(facemgr_t * facemgr, facelet_t * facelet)
return -2;
netdevice_t netdevice = NETDEVICE_EMPTY;
+
int rc = facelet_get_netdevice(facelet, &netdevice);
if (rc < 0) {
ERROR("[facemgr_complement_facelet_bj] Error retrieving netdevice from facelet");
@@ -1092,6 +1104,8 @@ facemgr_process_facelet(facemgr_t * facemgr, facelet_t * facelet)
facelet_unset_local_port(facelet);
facelet_unset_remote_addr(facelet);
facelet_unset_remote_port(facelet);
+ facelet_unset_admin_state(facelet);
+ facelet_unset_state(facelet);
facelet_unset_bj_done(facelet);
#ifdef WITH_ANDROID_UTILITY
facelet_unset_au_done(facelet);
@@ -1240,6 +1254,82 @@ facemgr_process_facelet_create(facemgr_t * facemgr, facelet_t * facelet)
return 0;
}
+/*
+ * \return 0 in case of success and no static facelet was added, 1 if a static
+ * facelet was added, and -1 in case of error.
+ */
+int
+facemgr_consider_static_facelet(facemgr_t * facemgr, facelet_t * facelet)
+{
+ /*
+ * We need to analyze the facelet and eventually:
+ * - add it in our static list
+ * - replicate it on multipath interfaces
+ */
+ netdevice_type_t netdevice_type;
+ if (facelet_get_netdevice_type(facelet, &netdevice_type) < 0)
+ return -1;
+
+ if ((netdevice_type == NETDEVICE_TYPE_UNDEFINED) ||
+ (netdevice_type == NETDEVICE_TYPE_LOOPBACK))
+ return 0;
+
+ if ((facelet_get_route_array(facelet, NULL) == 0))
+ return 0;
+
+ /*
+ * How to differenciate facelet created by face manager from user
+ * created ones ? This cannot be a flag in the facelet as it needs
+ * to work across restarts of the face manager...
+ * Also we might have two default routes.
+ *
+ * TODO:
+ * - The static one should not be a duplicate of the one we would
+ * create by default....
+ * - This should anyways be detected...
+ *
+ * One solution would be to install the default ones as static but
+ * this requires to implement a priority scheme between some of the
+ * static routes so that the override mechanism continues to work as
+ * usual.
+ *
+ * Current, we recognize the routes created by default by the face
+ * maanger thanks to the routing prefixes (a single default route).
+ */
+
+ facelet_t * static_facelet = facelet_dup(facelet);
+ facelet_unset_netdevice(static_facelet);
+ facelet_unset_netdevice_type(static_facelet);
+ facelet_unset_local_addr(static_facelet);
+ facelet_unset_local_port(static_facelet);
+
+ facelet_t * facelet_found = NULL;
+ if (facelet_array_get(facemgr->static_facelets, static_facelet, &facelet_found) < 0) {
+ ERROR("[facemgr_consider_static_facelet] Error checking whether static facelet already exists or not");
+ return -1;
+ }
+
+ /* Skip addition if facelet exists */
+ if (facelet_found)
+ return 0;
+
+ if (facelet_array_add(facemgr->static_facelets, static_facelet) < 0) {
+ ERROR("[facemgr_consider_static_facelet] Could not add facelet to static array");
+ facelet_free(static_facelet);
+ return -1;
+ }
+
+ char facelet_s[MAXSZ_FACELET];
+ int rc = facelet_snprintf(facelet_s, MAXSZ_FACELET, static_facelet);
+ if (rc >= MAXSZ_FACELET)
+ ERROR("[facemgr_consider_static_facelet] Unexpected truncation of facelet string");
+ if (rc < 0)
+ ERROR("[facemgr_consider_static_facelet] Error during facelet string output");
+ DEBUG("[facemgr_consider_static_facelet] Successfully added facelet to static array %s", facelet_s);
+
+ return 1;
+}
+
/**
* \brief Process facelet GET event
* \param [in] facemgr - Pointer to the face manager instance
@@ -1250,16 +1340,34 @@ facemgr_process_facelet_create(facemgr_t * facemgr, facelet_t * facelet)
int
facemgr_process_facelet_get(facemgr_t * facemgr, facelet_t * facelet)
{
- if (facelet_has_netdevice(facelet)) {
- netdevice_t netdevice;
- if (facelet_get_netdevice(facelet, &netdevice) < 0)
- return -1;
- if (!IS_VALID_NETDEVICE(netdevice))
- return -2;
- facelet_set_status(facelet, FACELET_STATUS_CLEAN);
- return facelet_set_add(facemgr->facelet_cache, facelet);
+ assert(facelet);
+
+ if (!facelet_has_netdevice(facelet))
+ return -2;
+
+ netdevice_t netdevice;
+ if (facelet_get_netdevice(facelet, &netdevice) < 0)
+ return -1;
+ if (!IS_VALID_NETDEVICE(netdevice))
+ return -2;
+ facelet_set_status(facelet, FACELET_STATUS_CLEAN);
+
+ int n = facemgr_consider_static_facelet(facemgr, facelet);
+ if (n < 0) {
+ ERROR("[facemgr_process_facelet_get] Could not add facelet to static array");
+ return -1;
}
- return -2;
+ if (n == 1) {
+ /*
+ * As a static facelet, it receives a new id not to be confused in the
+ * cache with default facelets
+ */
+ facelet_set_id(facelet, ++facemgr->cur_static_id);
+ }
+
+ char facelet_s[MAXSZ_FACELET];
+ facelet_snprintf(facelet_s, MAXSZ_FACELET, facelet);
+ return facelet_set_add(facemgr->facelet_cache, facelet);
}
/**
@@ -1354,6 +1462,9 @@ int facemgr_process_facelet_first_time(facemgr_t * facemgr, facelet_t * facelet)
{
facelet_set_status(facelet, FACELET_STATUS_UNCERTAIN);
+ assert(facelet);
+ char facelet_s[MAXSZ_FACELET];
+ facelet_snprintf(facelet_s, MAXSZ_FACELET, facelet);
if (facelet_set_add(facemgr->facelet_cache, facelet) < 0) {
ERROR("[facemgr_process_facelet_first_time] Error adding facelet to cache");
goto ERR_CACHE;
@@ -1385,15 +1496,28 @@ int
facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in)
{
bool remove_facelet = true;
+ bool dump = true;
int ret = 0;
int rc;
assert(facelet_in);
+ /* Update Netdevice type */
+ if (facelet_has_netdevice(facelet_in) && (!facelet_has_netdevice_type(facelet_in))) {
+ netdevice_t netdevice = NETDEVICE_EMPTY;
+
+ rc = facelet_get_netdevice(facelet_in, &netdevice);
+ if (rc < 0) {
+ ERROR("[facemgr_on_event] Error retrieving netdevice from facelet");
+ return -1;
+ }
+ facelet_set_netdevice_type(facelet_in, facemgr_get_netdevice_type(facemgr, netdevice.name));
+ }
+
char facelet_s[MAXSZ_FACELET];
facelet_snprintf(facelet_s, MAXSZ_FACELET, facelet_in);
- DEBUG("EVENT %s", facelet_s);
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");
@@ -1412,18 +1536,9 @@ facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in)
* Assumption: we should always see the link before the address
* assignment
*/
+ DEBUG("[facemgr_on_event] CREATE NEW %s", facelet_s);
assert(!facelet_has_family(facelet_in));
- if (!facelet_has_netdevice_type(facelet_in)) {
- netdevice_t netdevice = NETDEVICE_EMPTY;
- rc = facelet_get_netdevice(facelet_in, &netdevice);
- if (rc < 0) {
- ERROR("[facemgr_complement_facelet] Error retrieving netdevice from facelet");
- return -1;
- }
- facelet_set_netdevice_type(facelet_in, facemgr_get_netdevice_type(facemgr, netdevice.name));
- }
-
/* Create default v4 and v6 facelets */
facelet_t * facelet_v4 = facelet_dup(facelet_in);
if (!facelet_v4) {
@@ -1485,7 +1600,7 @@ facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in)
continue;
}
/* The id must be different than 0 */
- facelet_set_id(facelet_new, i+1);
+ facelet_set_id(facelet_new, ++facemgr->cur_static_id);
facelet_set_status(facelet_new, FACELET_STATUS_CLEAN);
char buf[MAXSZ_FACELET];
@@ -1506,9 +1621,11 @@ facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in)
case FACELET_EVENT_GET:
/* Insert new facelet in cached */
+ DEBUG("[facemgr_on_event] GET NEW %s", facelet_s);
rc = facemgr_process_facelet_get(facemgr, facelet_in);
if (rc == 0)
remove_facelet = false;
+ dump = false;
if (rc == -1) {
ERROR("[facemgr_on_event] Error processing GET event");
goto ERR;
@@ -1519,20 +1636,21 @@ facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in)
/* Might be because we previously ignored the facelet... */
//ERROR("[facemgr_on_event] Unexpected UPDATE... face does not exist");
//goto ERR;
+ DEBUG("[facemgr_on_event] UPDATE NEW %s", facelet_s);
INFO("Ignored UPDATE for non-existing face");
break;
case FACELET_EVENT_DELETE:
+ DEBUG("[facemgr_on_event] DELETE NEW %s", facelet_s);
ERROR("[facemgr_on_event] Unexpected DELETE... face does not exist");
goto ERR;
case FACELET_EVENT_UNDEFINED:
+ case FACELET_EVENT_N:
ERROR("[facemgr_on_event] Unexpected UNDEFINED event.");
+ ret = -1;
goto ERR;
- default: /* XXX Some events should be deprecated */
- ERROR("[facemgr_on_event] Deprecated event");
- goto ERR;
}
goto DUMP_CACHE;
}
@@ -1547,8 +1665,14 @@ facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in)
* reconciliation by sending appropriate updates to the forwarder
*/
facelet_t * facelet = cached_facelets[i];
+
+ char facelet_s[MAXSZ_FACELET];
+ facelet_snprintf(facelet_s, MAXSZ_FACELET, facelet);
+ //DEBUG("Facelet from cache #%d %s", i, facelet_s);
+
switch(facelet_get_event(facelet_in)) {
case FACELET_EVENT_CREATE:
+ DEBUG("[facemgr_on_event] CREATE EXISTING %s", facelet_s);
// 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
@@ -1565,13 +1689,17 @@ facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in)
continue;
case FACELET_EVENT_GET: /* should be an INFORM message */
- // FIXME, this might occur if the forwarder restarts and we
- // resync faces...
- ERROR("[facemgr_on_event] GET event for a face that already exists...");
- ret = -1;
+ /*
+ * This happens due to polling of the forwarder (or when it
+ * restarts)
+ */
+ DEBUG("[facemgr_on_event] GET EXISTING %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);
if (facelet_merge(facelet, facelet_in) < 0) {
ERROR("[facemgr_on_event] Error merging facelets");
continue;
@@ -1583,6 +1711,7 @@ facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in)
continue;
case FACELET_EVENT_DELETE:
+ DEBUG("[facemgr_on_event] DELETE EXISTING %s", facelet_s);
if (facelet_merge(facelet, facelet_in) < 0) {
ERROR("[facemgr_on_event] Error merging facelets");
continue;
@@ -1593,9 +1722,12 @@ facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in)
}
continue;
- default: /* XXX Some events should be deprecated */
- ERROR("[facemgr_on_event] Deprecated event");
+ case FACELET_EVENT_UNDEFINED:
+ case FACELET_EVENT_N:
+ ERROR("[facemgr_on_event] Unexpected UNDEFINED event.");
ret = -1;
+ goto ERR;
+
}
}
@@ -1606,11 +1738,13 @@ ERR:
DUMP_CACHE:
#if 1
- DEBUG(" <CACHE>");
- facelet_set_dump(facemgr->facelet_cache);
- DEBUG(" </CACHE>");
- DEBUG("</EVENT ret=%d>", ret);
- DEBUG("----------------------------------");
+ if (dump) {
+ DEBUG(" <CACHE>");
+ facelet_set_dump(facemgr->facelet_cache);
+ DEBUG(" </CACHE>");
+ DEBUG("</EVENT ret=%d>", ret);
+ DEBUG("----------------------------------");
+ }
#endif
free(cached_facelets);
diff --git a/ctrl/facemgr/src/facelet.c b/ctrl/facemgr/src/facelet.c
index 308302e22..761f920c4 100644
--- a/ctrl/facemgr/src/facelet.c
+++ b/ctrl/facemgr/src/facelet.c
@@ -233,7 +233,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;
@@ -244,7 +245,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;
}
@@ -411,13 +412,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;
}
@@ -493,7 +513,6 @@ do {
} \
} while(0)
-/* facelet_match is the incoming one */
bool
facelet_equals(const facelet_t * facelet1, const facelet_t * facelet2)
{
diff --git a/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c b/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c
index 76edfec10..53aa95a75 100644
--- a/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c
+++ b/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c
@@ -28,17 +28,23 @@
#include <hicn/util/log.h>
#include <hicn/util/map.h>
+#include "../../common.h"
#include "../../interface.h"
#define DEFAULT_ROUTE_COST 0
#define INTERVAL_MS 1000
+#define WITH_POLL
+
typedef enum {
HL_STATE_UNDEFINED,
- HL_STATE_CONNECTING,
+ HL_STATE_IDLE,
+ HL_STATE_ROUTES_SENT,
+ HL_STATE_ROUTES_RECEIVED,
HL_STATE_FACES_SENT,
- HL_STATE_DONE,
+ HL_STATE_FACES_RECEIVED,
+ HL_STATE_N
} hl_state_t;
typedef struct {
@@ -50,31 +56,63 @@ typedef struct {
/* Timer used to periodically poll the forwarder face and routing tables */
int poll_timer_fd;
+ hc_data_t * polled_routes;
} hl_data_t;
/* Forward declarations */
int hl_timeout(interface_t * interface, int fd, void * unused);
+#ifdef WITH_POLL
+int hl_process_state(interface_t * interface, int fd, void * unused)
+#else
int hl_process_state(interface_t * interface)
+#endif
{
hl_data_t * data = (hl_data_t *)interface->data;
+ /*
+ * Every tick we need to probe the forwarder for the list of faces and
+ * associated routes.
+ *
+ * This is used to guess manually added faces and routes
+ *
+ * TODO ensure we are idle at tick time
+ */
+
switch(data->state)
{
- case HL_STATE_UNDEFINED: // FIXME
- case HL_STATE_CONNECTING: // FIXME
- if (hc_face_list_async(data->s) < 0) {
- /* Blocking call */
- printf("Could not retrieve face list\n");
+ case HL_STATE_IDLE:
+ assert(!data->polled_routes);
+
+ //DEBUG("[hl_process_state] Querying route list");
+ if (hc_route_list_async(data->s) < 0) {
+ DEBUG("[hl_process_state] Error querying route list");
return -1;
}
+ data->state = HL_STATE_ROUTES_SENT;
break;
- case HL_STATE_FACES_SENT:
+
+ case HL_STATE_ROUTES_RECEIVED:
+ //DEBUG("[hl_process_state] Querying face list");
+ if (hc_face_list_async(data->s) < 0) {
+ DEBUG("[hl_process_state] Error querying face list");
+ return -1;
+ }
+ data->state = HL_STATE_FACES_SENT;
+ break;
break;
- default: /* HL_STATE_DONE never called */
+ case HL_STATE_FACES_RECEIVED:
+ data->state = HL_STATE_IDLE;
break;
+
+ case HL_STATE_ROUTES_SENT:
+ case HL_STATE_FACES_SENT:
+ case HL_STATE_UNDEFINED:
+ case HL_STATE_N:
+ ERROR("[hl_process_state] Unexpected state");
+ return -1;
}
return 0;
@@ -92,9 +130,21 @@ hl_after_connect(interface_t * interface)
goto ERR_FD;
}
- data->state = HL_STATE_UNDEFINED;
+ /* We always restart from the idle phase */
+ data->state = HL_STATE_IDLE;
+
+/* poll will replace the original get, ideally we would get notifications */
+#ifdef WITH_POLL
+ data->poll_timer_fd = interface_register_timer(interface, INTERVAL_MS,
+ hl_process_state, interface);
+ if (data->poll_timer_fd < 0) {
+ ERROR("[hc_connect] Could not initialize polling timer");
+ return -1;
+ }
+#else
hl_process_state(interface);
+#endif
return 0;
@@ -108,6 +158,10 @@ int _hl_connect(interface_t * interface);
int
hl_connect_timeout(interface_t * interface, int fd, void * unused)
{
+ hl_data_t * data = interface->data;
+ assert(fd == data->reconnect_timer_fd);
+ _unused(data);
+
int rc = _hl_connect(interface);
if (rc < 0) {
DEBUG("[hl_initialize] Error during connection reattempt; next attempt in %ds", INTERVAL_MS / 1000);
@@ -156,6 +210,12 @@ int hl_disconnect(interface_t * interface)
if (data->reconnect_timer_fd > 0)
interface_unregister_timer(interface, data->reconnect_timer_fd);
+ if (data->poll_timer_fd > 0)
+ interface_unregister_timer(interface, data->poll_timer_fd);
+
+ if (data->polled_routes)
+ hc_data_free(data->polled_routes);
+
if (data->s) {
interface_unregister_fd(interface, hc_sock_get_fd(data->s));
hc_sock_free(data->s);
@@ -194,6 +254,7 @@ hl_initialize(interface_t * interface, void * cfg)
data->s = NULL;
data->reconnect_timer_fd = 0;
+ data->poll_timer_fd = 0;
interface->data = data;
@@ -202,6 +263,8 @@ hl_initialize(interface_t * interface, void * cfg)
goto ERR_CONNECT;
}
+ data->polled_routes = NULL;
+
return 0;
ERR_CONNECT:
@@ -216,6 +279,9 @@ int hl_finalize(interface_t * interface)
hl_disconnect(interface);
+ if (data->polled_routes)
+ hc_data_free(data->polled_routes);
+
free(data);
return 0;
@@ -256,8 +322,10 @@ int hl_on_event(interface_t * interface, const facelet_t * facelet)
{
char buf[MAXSZ_FACELET];
facelet_snprintf(buf, MAXSZ_FACELET, facelet);
- printf("Create face %s\n", buf);
+ DEBUG("Create facelet %s", buf);
}
+ hc_face.id = 0;
+ memset(hc_face.name, 0, sizeof(hc_face.name));
hc_face.face = *face;
rc = hc_face_create(data->s, &hc_face);
if (rc < 0) {
@@ -399,38 +467,130 @@ ERR_FACE:
int hl_callback(interface_t * interface, int fd, void * unused)
{
hl_data_t * data = (hl_data_t*)interface->data;
+ hc_data_t * results;
+ int ret = 0;
- hc_data_t * faces;
- if (hc_sock_callback(data->s, &faces) < 0){
+ /* In case of error, reconnect to forwarder */
+ if (hc_sock_callback(data->s, &results) < 0) {
DEBUG("Closing socket... reconnecting...");
if (interface_unregister_fd(interface, hc_sock_get_fd(data->s)) < 0) {
- ERROR("[hl_initialize] Error registering fd");
+ ERROR("[hl_callback] Error unregistering fd");
+ }
+
+ /* Stopping poll timer */
+ if (interface_unregister_timer(interface, data->poll_timer_fd) < 0) {
+ ERROR("[hl_callback] Could not cancel polling timer after forwarder disconnect");
}
+ if (data->polled_routes)
+ hc_data_free(data->polled_routes);
+
hc_sock_free(data->s);
data->s = NULL;
hl_connect(interface);
- return 0;
+ return ret;
}
- if (faces->complete) {
- foreach_face(f, faces) {
+ /* Shall we wait for more data ? */
+ if (!results->complete)
+ return ret;
+
+ /* Process returned data */
+ switch(data->state) {
+
+ case HL_STATE_ROUTES_SENT:
+ //DEBUG("[hl_callback] Processing routes");
+ data->polled_routes = results;
+
#if 0
- char buf[MAXSZ_FACE];
- hc_face_snprintf(buf, MAXSZ_FACE, f);
- printf("Face: %s\n", buf);
+ foreach_route(r, results) {
+ char buf[MAXSZ_FACE];
+ int rc = hc_route_snprintf(route_s, MAXSZ_HC_ROUTE, r);
+ if (rc >= MAXSZ_HC_ROUTE)
+ ERROR("[hl_callback] Unexpected truncation of route string");
+ if (rc < 0)
+ ERROR("[hl_callback] Error during route string formatting");
+ DEBUG("Route: %s", buf);
+ }
#endif
- facelet_t * facelet = facelet_create_from_face(&f->face);
- facelet_set_event(facelet, FACELET_EVENT_GET);
- interface_raise_event(interface, facelet);
- }
- }
- hc_data_free(faces);
+ data->state = HL_STATE_ROUTES_RECEIVED;
+ if (hl_process_state(interface, fd, unused) < 0) {
+ ERROR("[hl_callback] Error processing state after routes received");
+ ret = -1;
+ }
+ break;
- /* XXX how do we know what object we get back */
- /* We have a queue of pending data elements per active query */
+ case HL_STATE_FACES_SENT:
+ //DEBUG("[hl_callback] Processing faces");
+ assert(data->polled_routes);
+ foreach_face(f, results) {
- return 0;
+#if 0
+ char buf[MAXSZ_FACE];
+ int rc = hc_face_snprintf(buf, MAXSZ_FACE, f);
+ if (rc >= MAXSZ_HC_FACE)
+ ERROR("[hl_callback] Unexpected truncation of face string");
+ if (rc < 0)
+ ERROR("[hl_callback] Error during face string formatting");
+
+ DEBUG("Face: %s", buf);
+#endif
+
+ /* We can ignore faces on localhost */
+
+ facelet_t * facelet = facelet_create_from_face(&f->face);
+ char facelet_s[MAXSZ_FACELET];
+ facelet_snprintf(facelet_s, MAXSZ_FACELET, facelet);
+ foreach_route(r, data->polled_routes) {
+ if (r->face_id != f->id)
+ continue;
+
+#if 0
+ char route_s[MAXSZ_HC_ROUTE];
+ int rc = hc_route_snprintf(route_s, MAXSZ_HC_ROUTE, r);
+ if (rc >= MAXSZ_HC_ROUTE)
+ ERROR("[hl_callback] Unexpected truncation of route string");
+ if (rc < 0)
+ ERROR("[hl_callback] Error during route string formatting");
+ DEBUG("Associated route: %s", route_s);
+#endif
+
+ if (r->len == 0)
+ continue;
+
+ ip_prefix_t prefix = {
+ .family = r->family,
+ .address = r->remote_addr,
+ .len = r->len,
+ };
+ hicn_route_t * route = hicn_route_create(&prefix, r->face_id, r->cost);
+ facelet_add_route(facelet, route);
+ }
+
+ facelet_snprintf(facelet_s, MAXSZ_FACELET, facelet);
+ facelet_set_event(facelet, FACELET_EVENT_GET);
+ interface_raise_event(interface, facelet);
+ }
+
+ hc_data_free(data->polled_routes);
+ data->polled_routes = NULL;
+ data->state = HL_STATE_FACES_RECEIVED;
+ if (hl_process_state(interface, fd, unused) < 0) {
+ ERROR("[hl_callback] Error processing state after faces received");
+ ret = -1;
+ }
+ break;
+
+ case HL_STATE_IDLE:
+ case HL_STATE_FACES_RECEIVED:
+ case HL_STATE_ROUTES_RECEIVED:
+ case HL_STATE_UNDEFINED:
+ case HL_STATE_N:
+ ERROR("[hl_callback] Unexpected state");
+ ret = -1;
+ }
+
+ return ret;
}
const interface_ops_t hicn_light_ops = {