From 94350c13fe983a7cfb99dafecb0d029ed58361bf Mon Sep 17 00:00:00 2001 From: Jordan Augé Date: Wed, 27 Nov 2019 09:05:39 +0100 Subject: [HICN-420] MAP-Me code refactoring & face manager changes in support of mobility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ifde50b4c161d1bda1326f18b705f575e539aea71 Signed-off-by: Jordan Augé --- ctrl/facemgr/includes/hicn/facemgr/facelet.h | 15 +- ctrl/facemgr/src/api.c | 326 +++++++++++++++------ ctrl/facemgr/src/facelet.c | 51 +++- ctrl/facemgr/src/interface.c | 2 +- ctrl/facemgr/src/interface.h | 4 +- .../interfaces/android_utility/android_utility.c | 2 +- ctrl/facemgr/src/interfaces/bonjour/bonjour.c | 2 +- ctrl/facemgr/src/interfaces/dummy/dummy.c | 2 +- .../facemgr/src/interfaces/hicn_light/hicn_light.c | 71 ++++- ctrl/facemgr/src/interfaces/netlink/netlink.c | 27 +- .../priority_controller/priority_controller.c | 4 +- ctrl/libhicnctrl/includes/hicn/ctrl/api.h | 2 + ctrl/libhicnctrl/includes/hicn/ctrl/commands.h | 8 + ctrl/libhicnctrl/src/api.c | 57 ++++ .../controller/hicnLightControl_main.c | 1 + hicn-light/src/hicn/config/configuration.c | 24 ++ hicn-light/src/hicn/core/connection.h | 1 + hicn-light/src/hicn/core/forwarder.c | 8 +- hicn-light/src/hicn/core/mapme.c | 217 ++++++++++---- hicn-light/src/hicn/core/mapme.h | 16 +- hicn-light/src/hicn/core/name.c | 4 + hicn-light/src/hicn/core/name.h | 1 + hicn-light/src/hicn/processor/fibEntry.c | 103 +++---- hicn-light/src/hicn/processor/fibEntry.h | 32 +- hicn-light/src/hicn/processor/messageProcessor.c | 15 - hicn-light/src/hicn/processor/messageProcessor.h | 5 - hicn-light/src/hicn/utils/commands.h | 8 + 27 files changed, 721 insertions(+), 287 deletions(-) diff --git a/ctrl/facemgr/includes/hicn/facemgr/facelet.h b/ctrl/facemgr/includes/hicn/facemgr/facelet.h index a0318b206..355af551d 100644 --- a/ctrl/facemgr/includes/hicn/facemgr/facelet.h +++ b/ctrl/facemgr/includes/hicn/facemgr/facelet.h @@ -71,6 +71,13 @@ typedef struct { face_type_encap_t encap; } facemgr_face_type_t; + +extern const char * face_type_layer_str[]; +extern const char * face_type_encap_str[]; + +#define FACEMGR_FACE_TYPE_STR(x) \ + face_type_layer_str[x.layer], face_type_encap_str[x.encap] + #define FACEMGR_FACE_TYPE_UNDEFINED (facemgr_face_type_t) { \ .layer = FACE_TYPE_LAYER_UNDEFINED, \ .encap = FACE_TYPE_ENCAP_UNDEFINED, \ @@ -96,10 +103,10 @@ typedef struct { .encap = FACE_TYPE_ENCAP_TCP, \ } - /* Facelet status */ #define foreach_facelet_status \ _(UNDEFINED) \ + _(DOWN) \ _(UNCERTAIN) \ _(INCOMPLETE) \ _(CREATE) \ @@ -194,6 +201,8 @@ extern const char * facelet_attr_status_str_short[]; _(CREATE) \ _(UPDATE) \ _(DELETE) \ + _(SET_UP) \ + _(SET_DOWN) \ _(N) #define MAXSZ_EVENT__ 10 @@ -246,6 +255,8 @@ bool facelet_has_key(const facelet_t * facelet); #define FACELET_ACCESSORS_H(TYPE, NAME) \ bool facelet_has_ ## NAME(const facelet_t * facelet); \ facelet_attr_status_t facelet_get_ ## NAME ## _status(const facelet_t * facelet);\ +void facelet_set_ ## NAME ## _status(facelet_t * facelet, \ + facelet_attr_status_t status); \ int facelet_get_ ## NAME(const facelet_t * facelet, TYPE * NAME); \ int facelet_set_ ## NAME(facelet_t * facelet, TYPE NAME); \ int facelet_unset_ ## NAME(facelet_t * facelet); @@ -256,7 +267,7 @@ foreach_facelet_attr int facelet_get_face(const facelet_t * facelet, face_t ** pface); -int facelet_merge(facelet_t * facelet, const facelet_t * facelet_to_merge); +int facelet_merge(facelet_t * facelet, 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); 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; } diff --git a/ctrl/facemgr/src/facelet.c b/ctrl/facemgr/src/facelet.c index a6231f457..2308f3b6d 100644 --- a/ctrl/facemgr/src/facelet.c +++ b/ctrl/facemgr/src/facelet.c @@ -44,9 +44,6 @@ const char * face_type_encap_str[] = { #undef _ }; -#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 @@ -593,6 +590,13 @@ facelet_get_ ## NAME ## _status(const facelet_t * facelet) return (facelet->NAME ## _status); \ } \ \ +void \ +facelet_set_ ## NAME ## _status(facelet_t * facelet, \ + facelet_attr_status_t status) \ +{ \ + facelet->NAME ## _status = status; \ +} \ + \ int \ facelet_get_ ## NAME(const facelet_t * facelet, TYPE * NAME) \ { \ @@ -701,9 +705,10 @@ do { } \ } while (0) -int facelet_merge(facelet_t * facelet, const facelet_t * facelet_to_merge) +int facelet_merge(facelet_t * facelet, facelet_t * facelet_to_merge) { assert(facelet && facelet_to_merge); + #define _(TYPE, NAME) MERGE_ATTRIBUTE(TYPE, NAME); foreach_facelet_attr #undef _ @@ -716,7 +721,7 @@ int facelet_merge(facelet_t * facelet, const facelet_t * facelet_to_merge) ERROR("[facelet_free] Error getting route set associated to facelet"); } else { for (unsigned i = 0; i < n; i++) { - hicn_route_t * route = route_array[i]; + hicn_route_t * route = hicn_route_dup(route_array[i]); route_set_add(facelet->routes, route); } } @@ -760,8 +765,10 @@ facelet_get_face(const facelet_t * facelet, face_t ** pface) assert(pface); /* Facelet has all the required information to create a face */ - if (facelet_validate_face(facelet) < 0) + if (facelet_validate_face(facelet) < 0) { + ERROR("[facelet_get_face] Face does not validate"); return 0; + } face_t * face = face_create(); if (!face) @@ -786,16 +793,26 @@ facelet_get_face(const facelet_t * facelet, face_t ** pface) goto ERR; } - if (facelet_get_family(facelet, &face->family) < 0) + if (facelet_get_family(facelet, &face->family) < 0) { + ERROR("[facelet_get_face] Error retrieving face family"); goto ERR; - if (facelet_get_local_addr(facelet, &face->local_addr) < 0) + } + if (facelet_get_local_addr(facelet, &face->local_addr) < 0) { + ERROR("[facelet_get_face] Error retrieving face local address"); goto ERR; - if (facelet_get_local_port(facelet, &face->local_port) < 0) + } + if (facelet_get_local_port(facelet, &face->local_port) < 0) { + ERROR("[facelet_get_face] Error retrieving face local port"); goto ERR; - if (facelet_get_remote_addr(facelet, &face->remote_addr) < 0) + } + if (facelet_get_remote_addr(facelet, &face->remote_addr) < 0) { + ERROR("[facelet_get_face] Error retrieving face remote address"); goto ERR; - if (facelet_get_remote_port(facelet, &face->remote_port) < 0) + } + if (facelet_get_remote_port(facelet, &face->remote_port) < 0) { + ERROR("[facelet_get_face] Error retrieving face remote port"); goto ERR; + } break; case FACE_TYPE_LAYER_3: @@ -809,15 +826,19 @@ facelet_get_face(const facelet_t * facelet, face_t ** pface) } if (facelet_has_admin_state(facelet)) { - if (facelet_get_admin_state(facelet, &face->admin_state) < 0) + if (facelet_get_admin_state(facelet, &face->admin_state) < 0) { + ERROR("[facelet_get_face] Error getting face admin state"); goto ERR; + } } else { face->admin_state = FACE_STATE_UP; } if (facelet_has_state(facelet)) { - if (facelet_get_state(facelet, &face->state) < 0) + if (facelet_get_state(facelet, &face->state) < 0) { + ERROR("[facelet_get_face] Error getting face state"); goto ERR; + } } else { face->state = FACE_STATE_UP; } @@ -825,8 +846,10 @@ facelet_get_face(const facelet_t * facelet, face_t ** pface) #ifdef WITH_POLICY /* Priority */ if (facelet_has_priority(facelet)) { - if (facelet_get_priority(facelet, &face->priority) < 0) + if (facelet_get_priority(facelet, &face->priority) < 0) { + ERROR("[facelet_get_face] Error getting face priority"); goto ERR; + } } else { face->priority = 0; } diff --git a/ctrl/facemgr/src/interface.c b/ctrl/facemgr/src/interface.c index 3d6328d6d..7f95be4ce 100644 --- a/ctrl/facemgr/src/interface.c +++ b/ctrl/facemgr/src/interface.c @@ -128,7 +128,7 @@ interface_finalize(interface_t * interface) } int -interface_on_event(interface_t * interface, const facelet_t * facelet) +interface_on_event(interface_t * interface, facelet_t * facelet) { if (!interface->ops->on_event) return -1; diff --git a/ctrl/facemgr/src/interface.h b/ctrl/facemgr/src/interface.h index 627a3645e..a4fbda1fb 100644 --- a/ctrl/facemgr/src/interface.h +++ b/ctrl/facemgr/src/interface.h @@ -55,7 +55,7 @@ typedef struct { /* Callback upon file descriptor event (iif previously registered) */ int (*callback)(struct interface_s * interface, int fd, void * data); /* Callback upon face events coming from the face manager */ - int (*on_event)(struct interface_s * interface, const struct facelet_s * facelet); + int (*on_event)(struct interface_s * interface, struct facelet_s * facelet); } interface_ops_t; typedef struct interface_s { @@ -106,7 +106,7 @@ int interface_initialize(interface_t * interface, void * cfg); int interface_finalize(interface_t * interface); -int interface_on_event(interface_t * interface, const struct facelet_s * facelet); +int interface_on_event(interface_t * interface, struct facelet_s * facelet); /** * \brief Raises a facelet event to the face manager diff --git a/ctrl/facemgr/src/interfaces/android_utility/android_utility.c b/ctrl/facemgr/src/interfaces/android_utility/android_utility.c index e7c73df8b..47d3cd106 100644 --- a/ctrl/facemgr/src/interfaces/android_utility/android_utility.c +++ b/ctrl/facemgr/src/interfaces/android_utility/android_utility.c @@ -71,7 +71,7 @@ int au_finalize(interface_t * interface) return 0; } -int au_on_event(interface_t * interface, const facelet_t * facelet) +int au_on_event(interface_t * interface, facelet_t * facelet) { /* * This function is responsible to annotate every face we receive with the diff --git a/ctrl/facemgr/src/interfaces/bonjour/bonjour.c b/ctrl/facemgr/src/interfaces/bonjour/bonjour.c index 10e757245..40b7f5f90 100644 --- a/ctrl/facemgr/src/interfaces/bonjour/bonjour.c +++ b/ctrl/facemgr/src/interfaces/bonjour/bonjour.c @@ -133,7 +133,7 @@ ERR_MALLOC: * We reuse the callback to be triggered upon external events * TODO: move to a cleaner interface architecture later... */ -int bj_on_event(interface_t * interface, const facelet_t * facelet) +int bj_on_event(interface_t * interface, facelet_t * facelet) { bj_data_t * data = (bj_data_t*)interface->data; diff --git a/ctrl/facemgr/src/interfaces/dummy/dummy.c b/ctrl/facemgr/src/interfaces/dummy/dummy.c index 25180465e..69c336e57 100644 --- a/ctrl/facemgr/src/interfaces/dummy/dummy.c +++ b/ctrl/facemgr/src/interfaces/dummy/dummy.c @@ -106,7 +106,7 @@ int dummy_callback(interface_t * interface) return 0; } -int dummy_on_event(interface_t * interface, const facelet_t * facelet) +int dummy_on_event(interface_t * interface, facelet_t * facelet) { dummy_data_t * data = (dummy_data_t*)interface->data; UNUSED(data); diff --git a/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c b/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c index cb1a0040d..71243aea1 100644 --- a/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c +++ b/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c @@ -286,7 +286,7 @@ int hl_finalize(interface_t * interface) return 0; } -int hl_on_event(interface_t * interface, const facelet_t * facelet) +int hl_on_event(interface_t * interface, facelet_t * facelet) { hc_face_t hc_face; hc_route_t route; @@ -399,6 +399,7 @@ int hl_on_event(interface_t * interface, const facelet_t * facelet) } } } + free(route_array); break; @@ -447,9 +448,71 @@ int hl_on_event(interface_t * interface, const facelet_t * facelet) ret = -FACELET_ERROR_REASON_UNSPECIFIED_ERROR; goto ERR; } + facelet_set_admin_state_status(facelet, FACELET_ATTR_STATUS_CLEAN); INFO("Admin state updated"); } +#ifdef WITH_POLICY + if (facelet_get_netdevice_type_status(facelet) == FACELET_ATTR_STATUS_DIRTY) { + hc_face.face = *face; + hc_face_t * face_found; + + rc = hc_face_get(data->s, &hc_face, &face_found); + if (rc < 0) { + ERROR("Failed to find face\n"); + goto ERR; + } + if (!face_found) { + ERROR("Face to update has not been found"); + goto ERR; + } + char conn_id_or_name[SYMBOLIC_NAME_LEN]; + snprintf(conn_id_or_name, SYMBOLIC_NAME_LEN, "%d", face_found->id); + free(face_found); + + netdevice_type_t netdevice_type; + if (facelet_get_netdevice_type(facelet, &netdevice_type) < 0) { + ERROR("Failed to retrieve facelet netdevice_type"); + goto ERR; + } + + /* Encode netdevice type into tags */ + policy_tags_t tags = POLICY_TAGS_EMPTY; + if (facelet_has_netdevice_type(facelet)) { + netdevice_type_t netdevice_type; + if (facelet_get_netdevice_type(facelet, &netdevice_type) < 0) { + ERROR("error getting netdevice_type"); + goto ERR; + } + + + switch(netdevice_type) { + case NETDEVICE_TYPE_UNDEFINED: + case NETDEVICE_TYPE_LOOPBACK: + break; + case NETDEVICE_TYPE_WIRED: + policy_tags_add(&tags, POLICY_TAG_WIRED); + break; + case NETDEVICE_TYPE_WIFI: + policy_tags_add(&tags, POLICY_TAG_WIFI); + break; + case NETDEVICE_TYPE_CELLULAR: + policy_tags_add(&tags, POLICY_TAG_CELLULAR); + break; + default: + goto ERR; + } + } + //face->tags = tags; + + if (hc_connection_set_tags(data->s, conn_id_or_name, tags) < 0) { + ERROR("Failed to update tags"); + goto ERR; + } + facelet_set_netdevice_type_status(facelet, FACELET_ATTR_STATUS_CLEAN); + INFO("Tags updated"); + } if (facelet_get_priority_status(facelet) == FACELET_ATTR_STATUS_DIRTY) { + INFO("Updating priority..."); hc_face.face = *face; hc_face_t * face_found; @@ -472,12 +535,15 @@ int hl_on_event(interface_t * interface, const facelet_t * facelet) goto ERR; } + INFO("Changing connection %s priority to %d", conn_id_or_name, priority); if (hc_connection_set_priority(data->s, conn_id_or_name, priority) < 0) { ERROR("Failed to update priority"); goto ERR; } + facelet_set_priority_status(facelet, FACELET_ATTR_STATUS_CLEAN); INFO("Priority updated"); } +#endif /* WITH_POLICY */ break; default: @@ -568,8 +634,6 @@ int hl_callback(interface_t * interface, int fd, void * unused) /* 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; @@ -596,7 +660,6 @@ int hl_callback(interface_t * interface, int fd, void * unused) facelet_add_route(facelet, route); } - facelet_snprintf(facelet_s, MAXSZ_FACELET, facelet); facelet_set_event(facelet, FACELET_EVENT_GET); interface_raise_event(interface, facelet); } diff --git a/ctrl/facemgr/src/interfaces/netlink/netlink.c b/ctrl/facemgr/src/interfaces/netlink/netlink.c index 62d4fdf90..4d92f2511 100644 --- a/ctrl/facemgr/src/interfaces/netlink/netlink.c +++ b/ctrl/facemgr/src/interfaces/netlink/netlink.c @@ -309,13 +309,6 @@ int parse_addr(struct nlmsghdr * h, facelet_t ** facelet, return 0; } -#if 0 /* Not working for v6 */ - if (interface_name) { - assert(tba[IFLA_IFNAME]); - snprintf(interface_name, interface_name_size, "%s", (char*)RTA_DATA(tba[IFLA_IFNAME])); - } -#endif - /* See comment in parse_link */ if (interface_address) { assert(tba[IFA_ADDRESS]); @@ -324,7 +317,7 @@ int parse_addr(struct nlmsghdr * h, facelet_t ** facelet, netdevice_t * netdevice = netdevice_create_from_index(ifa->ifa_index); if (!netdevice) { - ERROR("[netlink.parse_addr] error creating netdevice '%s'", interface_name); + ERROR("[netlink.parse_addr] error creating netdevice from index '%d'", ifa->ifa_index); goto ERR_ND; } @@ -432,9 +425,9 @@ int nl_callback(interface_t * interface, int fd, void * unused) break; } - //DEBUG("Interface %s: address was removed", interface_name); + DEBUG("Interface %s: address was removed", interface_name); if (facelet) { - facelet_set_event(facelet, FACELET_EVENT_DELETE); + facelet_set_event(facelet, FACELET_EVENT_SET_DOWN); facelet_set_status(facelet, FACELET_STATUS_CLEAN); interface_raise_event(interface, facelet); } @@ -453,7 +446,7 @@ int nl_callback(interface_t * interface, int fd, void * unused) break; } - //DEBUG("Interface %s: new address was assigned: %s", interface_name, interface_address); + DEBUG("Interface %s: new address was assigned: %s", interface_name, interface_address); if (facelet) { facelet_set_event(facelet, FACELET_EVENT_UPDATE); @@ -465,6 +458,8 @@ int nl_callback(interface_t * interface, int fd, void * unused) case RTM_DELLINK: { + /* This does not always seem to be called, hence we rely on + * down, not running */ facelet_t * facelet = NULL; char interface_name[IFNAMSIZ]; if (parse_link(h, &facelet, interface_name, IFNAMSIZ, @@ -473,7 +468,7 @@ int nl_callback(interface_t * interface, int fd, void * unused) break; } - //DEBUG("Network interface %s was removed", interface_name); + DEBUG("Network interface %s was removed", interface_name); if (!facelet) break; @@ -499,7 +494,7 @@ int nl_callback(interface_t * interface, int fd, void * unused) // UP RUNNING // UP NOT RUNNING // DOWN NOT RUNNING -#if 0 +#if 1 DEBUG("New network interface %s, state: %s %s", interface_name, up ? "UP" : "DOWN", running ? "RUNNING" : "NOT_RUNNING"); @@ -523,7 +518,13 @@ int nl_callback(interface_t * interface, int fd, void * unused) interface_raise_event(interface, facelet6); #endif } else { +#if 1 + facelet_set_event(facelet, FACELET_EVENT_SET_DOWN); + facelet_set_status(facelet, FACELET_STATUS_CLEAN); + interface_raise_event(interface, facelet); +#else facelet_free(facelet); +#endif } break; } diff --git a/ctrl/facemgr/src/interfaces/priority_controller/priority_controller.c b/ctrl/facemgr/src/interfaces/priority_controller/priority_controller.c index a64796857..5452c0e85 100644 --- a/ctrl/facemgr/src/interfaces/priority_controller/priority_controller.c +++ b/ctrl/facemgr/src/interfaces/priority_controller/priority_controller.c @@ -30,6 +30,8 @@ #include "../../common.h" #include "../../interface.h" +#define PC_DEFAULT_PORT 9533 + typedef struct { int fd; } pc_data_t; @@ -58,7 +60,7 @@ int priority_controller_initialize(interface_t * interface, void * cfg) memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr("127.0.0.1"); - addr.sin_port = htons(9533); + addr.sin_port = htons(PC_DEFAULT_PORT); if (bind(data->fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) { INFO("Priority controller socket bind error"); diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/api.h b/ctrl/libhicnctrl/includes/hicn/ctrl/api.h index 068b3eb08..65633c249 100644 --- a/ctrl/libhicnctrl/includes/hicn/ctrl/api.h +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/api.h @@ -527,6 +527,7 @@ int hc_connection_parse(void *in, hc_connection_t *connection); int hc_connection_set_admin_state(hc_sock_t * s, const char * conn_id_or_name, face_state_t state); #ifdef WITH_POLICY int hc_connection_set_priority(hc_sock_t * s, const char * conn_id_or_name, uint32_t priority); +int hc_connection_set_tags(hc_sock_t * s, const char * conn_id_or_name, policy_tags_t tags); #endif /* WITH_POLICY */ #define foreach_connection(VAR, data) foreach_type(hc_connection_t, VAR, data) @@ -575,6 +576,7 @@ int hc_face_list_async(hc_sock_t *s); //, hc_data_t ** pdata); int hc_face_set_admin_state(hc_sock_t * s, const char * conn_id_or_name, face_state_t state); #ifdef WITH_POLICY int hc_face_set_priority(hc_sock_t * s, const char * conn_id_or_name, uint32_t priority); +int hc_face_set_tags(hc_sock_t * s, const char * conn_id_or_name, policy_tags_t tags); #endif /* WITH_POLICY */ #define foreach_face(VAR, data) foreach_type(hc_face_t, VAR, data) diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/commands.h b/ctrl/libhicnctrl/includes/hicn/ctrl/commands.h index c250216f0..bb566e688 100644 --- a/ctrl/libhicnctrl/includes/hicn/ctrl/commands.h +++ b/ctrl/libhicnctrl/includes/hicn/ctrl/commands.h @@ -76,6 +76,7 @@ typedef enum { REMOVE_POLICY, UPDATE_CONNECTION, CONNECTION_SET_PRIORITY, + CONNECTION_SET_TAGS, #endif /* WITH_POLICY */ LAST_COMMAND_VALUE } command_id; @@ -345,6 +346,11 @@ typedef struct { uint32_t priority; } connection_set_priority_command; +typedef struct { + char symbolicOrConnid[SYMBOLIC_NAME_LEN]; + policy_tags_t tags; +} connection_set_tags_command; + #endif /* WITH_POLICY */ //===== size of commands ====== @@ -403,6 +409,8 @@ static inline int payloadLengthDaemon(command_id id) { return sizeof(update_connection_command); case CONNECTION_SET_PRIORITY: return sizeof(connection_set_priority_command); + case CONNECTION_SET_TAGS: + return sizeof(connection_set_tags_command); #endif /* WITH_POLICY */ case LAST_COMMAND_VALUE: return 0; diff --git a/ctrl/libhicnctrl/src/api.c b/ctrl/libhicnctrl/src/api.c index f7efd6b44..8a81c6c5f 100644 --- a/ctrl/libhicnctrl/src/api.c +++ b/ctrl/libhicnctrl/src/api.c @@ -1711,6 +1711,56 @@ hc_connection_set_priority_async(hc_sock_t * s, const char * conn_id_or_name, return _hc_connection_set_priority(s, conn_id_or_name, priority, true); } +int +_hc_connection_set_tags(hc_sock_t * s, const char * conn_id_or_name, + policy_tags_t tags, bool async) +{ + int rc; + DEBUG("[hc_connection_set_tags] connection_id/name=%s tags=%d async=%s", + conn_id_or_name, tags, BOOLSTR(async)); + struct { + header_control_message hdr; + connection_set_tags_command payload; + } msg = { + .hdr = { + .messageType = REQUEST_LIGHT, + .commandID = CONNECTION_SET_TAGS, + .length = 1, + .seqNum = 0, + }, + .payload = { + .tags = tags, + }, + }; + rc = snprintf(msg.payload.symbolicOrConnid, SYMBOLIC_NAME_LEN, "%s", conn_id_or_name); + if (rc >= SYMBOLIC_NAME_LEN) + WARN("[_hc_connection_set_tags] Unexpected truncation of symbolic name string"); + + hc_command_params_t params = { + .cmd = ACTION_SET, + .cmd_id = CONNECTION_SET_TAGS, + .size_in = sizeof(connection_set_tags_command), + .size_out = 0, + .parse = NULL, + }; + + return hc_execute_command(s, (hc_msg_t*)&msg, sizeof(msg), ¶ms, NULL, async); +} + +int +hc_connection_set_tags(hc_sock_t * s, const char * conn_id_or_name, + policy_tags_t tags) +{ + return _hc_connection_set_tags(s, conn_id_or_name, tags, false); +} + +int +hc_connection_set_tags_async(hc_sock_t * s, const char * conn_id_or_name, + policy_tags_t tags) +{ + return _hc_connection_set_tags(s, conn_id_or_name, tags, true); +} + /*----------------------------------------------------------------------------* * Routes *----------------------------------------------------------------------------*/ @@ -2559,6 +2609,13 @@ hc_face_set_priority(hc_sock_t * s, const char * conn_id_or_name, return hc_connection_set_priority(s, conn_id_or_name, priority); } +int +hc_face_set_tags(hc_sock_t * s, const char * conn_id_or_name, + policy_tags_t tags) +{ + return hc_connection_set_tags(s, conn_id_or_name, tags); +} + /*----------------------------------------------------------------------------* * Punting *----------------------------------------------------------------------------*/ diff --git a/hicn-light/src/hicn/command_line/controller/hicnLightControl_main.c b/hicn-light/src/hicn/command_line/controller/hicnLightControl_main.c index 1f5d33e24..739326669 100644 --- a/hicn-light/src/hicn/command_line/controller/hicnLightControl_main.c +++ b/hicn-light/src/hicn/command_line/controller/hicnLightControl_main.c @@ -83,6 +83,7 @@ static int payloadLengthController[LAST_COMMAND_VALUE] = { sizeof(remove_policy_command), sizeof(update_connection_command), sizeof(connection_set_priority_command), + sizeof(connection_set_tags_command), #endif }; diff --git a/hicn-light/src/hicn/config/configuration.c b/hicn-light/src/hicn/config/configuration.c index 0466189cb..52dbf7a47 100644 --- a/hicn-light/src/hicn/config/configuration.c +++ b/hicn-light/src/hicn/config/configuration.c @@ -1197,6 +1197,26 @@ struct iovec *configuration_ConnectionSetPriority(Configuration *config, return utils_CreateAck(header, control, sizeof(connection_set_priority_command)); } +struct iovec *configuration_ConnectionSetTags(Configuration *config, + struct iovec *request) { + header_control_message *header = request[0].iov_base; + connection_set_tags_command *control = request[1].iov_base; + + Connection * conn = getConnectionBySymbolicOrId(config, control->symbolicOrConnid); + if (!conn) + return utils_CreateNack(header, control, sizeof(connection_set_tags_command)); + + connection_SetTags(conn, control->tags); + +#ifdef WITH_MAPME + /* Hook: connection event */ + forwarder_onConnectionEvent(config->forwarder, conn, + CONNECTION_EVENT_TAGS_CHANGED); +#endif /* WITH_MAPME */ + + return utils_CreateAck(header, control, sizeof(connection_set_tags_command)); +} + struct iovec *configuration_ProcessPolicyAdd(Configuration *config, struct iovec *request) { header_control_message *header = request[0].iov_base; @@ -1402,6 +1422,10 @@ struct iovec *configuration_DispatchCommand(Configuration *config, case CONNECTION_SET_PRIORITY: response = configuration_ConnectionSetPriority(config, control); break; + + case CONNECTION_SET_TAGS: + response = configuration_ConnectionSetTags(config, control); + break; #endif /* WITH_POLICY */ default: diff --git a/hicn-light/src/hicn/core/connection.h b/hicn-light/src/hicn/core/connection.h index 3b647dd7a..d0d093064 100644 --- a/hicn-light/src/hicn/core/connection.h +++ b/hicn-light/src/hicn/core/connection.h @@ -37,6 +37,7 @@ typedef enum { CONNECTION_EVENT_SET_UP, CONNECTION_EVENT_SET_DOWN, CONNECTION_EVENT_PRIORITY_CHANGED, + CONNECTION_EVENT_TAGS_CHANGED, } connection_event_t; #endif /* WITH_MAPME */ diff --git a/hicn-light/src/hicn/core/forwarder.c b/hicn-light/src/hicn/core/forwarder.c index 66551b0ec..628cbd761 100644 --- a/hicn-light/src/hicn/core/forwarder.c +++ b/hicn-light/src/hicn/core/forwarder.c @@ -571,11 +571,11 @@ FIB *forwarder_getFib(Forwarder *forwarder) { } void forwarder_onConnectionEvent(Forwarder *forwarder, const Connection *conn, connection_event_t event) { -#ifdef WITH_POLICY - messageProcessor_onConnectionEvent(forwarder->processor, conn, event); -#else +//#ifdef WITH_POLICY +// messageProcessor_onConnectionEvent(forwarder->processor, conn, event); +//#else mapme_onConnectionEvent(forwarder->mapme, conn, event); -#endif /* WITH_POLICY */ +//#endif /* WITH_POLICY */ } void forwarder_ProcessMapMe(Forwarder *forwarder, const uint8_t *msgBuffer, diff --git a/hicn-light/src/hicn/core/mapme.c b/hicn-light/src/hicn/core/mapme.c index 0eba02e49..d5475f229 100644 --- a/hicn-light/src/hicn/core/mapme.c +++ b/hicn-light/src/hicn/core/mapme.c @@ -146,6 +146,7 @@ ERR_MALLOC: void mapmeTFIB_Release(MapMeTFIB **tfibPtr) { MapMeTFIB *tfib = *tfibPtr; + /* TODO; Release all timers */ parcHashMap_Release(&tfib->nexthops); free(tfib); *tfibPtr = NULL; @@ -282,13 +283,13 @@ struct setFacePendingArgs { FibEntry *fibEntry; unsigned conn_id; bool send; - bool is_first; + bool is_producer; uint32_t num_retx; }; static bool mapme_setFacePending(const MapMe *mapme, const Name *name, FibEntry *fibEntry, unsigned conn_id, - bool send, bool is_first, uint32_t num_retx); + bool send, bool is_producer, bool clear_tfib, uint32_t num_retx); static void mapme_setFacePendingCallback(int fd, PARCEventType which_event, void *data) { @@ -300,7 +301,7 @@ static void mapme_setFacePendingCallback(int fd, PARCEventType which_event, INFO(args->mapme, "Timeout during retransmission. Re-sending"); mapme_setFacePending(args->mapme, args->name, args->fibEntry, args->conn_id, - args->send, args->is_first, args->num_retx); + args->send, args->is_producer, false, args->num_retx); } /** @@ -325,7 +326,7 @@ static hicn_mapme_type_t mapme_getTypeFromHeuristic(const MapMe *mapme, static bool mapme_setFacePending(const MapMe *mapme, const Name *name, FibEntry *fibEntry, unsigned conn_id, - bool send, bool is_first, uint32_t num_retx) { + bool send, bool is_producer, bool clear_tfib, uint32_t num_retx) { int rc; INFO(mapme, "[MAP-Me] SetFacePending connection=%d prefix=XX retx=%d", @@ -337,14 +338,46 @@ static bool mapme_setFacePending(const MapMe *mapme, const Name *name, Dispatcher *dispatcher = forwarder_GetDispatcher(mapme->forwarder); PARCEventTimer *timer; + /* + * On the producer side, we have to clear the TFIB everytime we change the list + * of adjacencies, otherwise retransmissions will occur to preserve them. + */ + if (clear_tfib) { + /* + * It is likely we cannot iterator and remove elements from the hashmap at + * the same time, so we proceed in two steps + */ + NumberSet * conns = numberSet_Create(); + + PARCIterator *it = parcHashMap_CreateKeyIterator(TFIB(fibEntry)->nexthops); + while (parcIterator_HasNext(it)) { + PARCUnsigned *cid = parcIterator_Next(it); + unsigned conn_id = parcUnsigned_GetUnsigned(cid); + numberSet_Add(conns, conn_id); + } + parcIterator_Release(&it); + + for (size_t i = 0; i < numberSet_Length(conns); i++) { + unsigned conn_id = numberSet_GetItem(conns, i); + PARCEventTimer *oldTimer = (PARCEventTimer *)mapmeTFIB_Get(TFIB(fibEntry), conn_id); + if (oldTimer) + parcEventTimer_Stop(oldTimer); + mapmeTFIB_Remove(TFIB(fibEntry), conn_id); + } + + numberSet_Release(&conns); + } + + // NOTE // - at producer, send always true, we always send something reliably so we // set the timer. // - in the network, we always forward an IU, and never an IN - if (is_first || send) { + //if (is_producer || send) { + if (send) { mapme_params_t params = { .protocol = IPPROTO_IPV6, - .type = is_first ? mapme_getTypeFromHeuristic(mapme, fibEntry) : UPDATE, + .type = is_producer ? mapme_getTypeFromHeuristic(mapme, fibEntry) : UPDATE, .seq = TFIB(fibEntry)->seq}; Message *special_interest = mapme_createMessage(mapme, name, ¶ms); if (!special_interest) { @@ -378,7 +411,7 @@ static bool mapme_setFacePending(const MapMe *mapme, const Name *name, args->fibEntry = fibEntry; args->conn_id = conn_id; args->send = send; - args->is_first = is_first; + args->is_producer = is_producer; args->num_retx = num_retx + 1; timer = dispatcher_CreateTimer(dispatcher, TIMER_NO_REPEAT, @@ -440,59 +473,103 @@ static bool mapme_hasLocalNextHops(const MapMe *mapme, return false; } +void +mapme_reconsiderFibEntry(const MapMe *mapme, FibEntry * fibEntry) +{ + /* + * Skip entries that do not correspond to a producer ( / have a locally + * served prefix / have no local connection as next hop) + */ + if (!mapme_hasLocalNextHops(mapme, fibEntry)) + return; + + /* Apply the policy of the fibEntry over all neighbours */ + NumberSet * available_nexthops = fibEntry_GetAvailableNextHops(fibEntry, ~0); + NumberSet * previous_nexthops = fibEntry_GetPreviousNextHops(fibEntry); + + /* Detect change */ + if (numberSet_Equals(available_nexthops, previous_nexthops)) { + numberSet_Release(&available_nexthops); + INFO(mapme, "[MAP-Me] No change in nexthops"); + return; + } + fibEntry_SetPreviousNextHops(fibEntry, available_nexthops); + + + /* Advertise prefix on all available next hops */ + if (!TFIB(fibEntry)) /* Create TFIB associated to FIB entry */ + mapme_CreateTFIB(fibEntry); + TFIB(fibEntry)->seq++; + + const Name *name = fibEntry_GetPrefix(fibEntry); + char *name_str = name_ToString(name); + bool clear_tfib = true; + for (size_t j = 0; j < numberSet_Length(available_nexthops); j++) { + unsigned nexthop_id = numberSet_GetItem(available_nexthops, j); + INFO(mapme, "[MAP-Me] sending IU/IN for name %s on connection %d", name_str, + nexthop_id); + mapme_setFacePending(mapme, name, fibEntry, nexthop_id, true, true, clear_tfib, 0); + clear_tfib = false; + } + free(name_str); + + numberSet_Release(&available_nexthops); +} + /* * Callback called everytime a new connection is created by the control protocol */ -void mapme_onConnectionEvent(const MapMe *mapme, const Connection *conn_added, connection_event_t event) { - switch(event) { - case CONNECTION_EVENT_CREATE: - case CONNECTION_EVENT_SET_UP: - { - FibEntryList *fiblist; - - /* Ignore local connections corresponding to applications for now */ - if (connection_IsLocal(conn_added)) - return; - - unsigned conn_added_id = connection_GetConnectionId(conn_added); - INFO(mapme, "[MAP-Me] New connection %d", conn_added_id); - - /* - * Iterate on FIB to find locally served prefix - * Ideally, we want to avoid a FIB scan everytime a face is added/removed - */ - fiblist = forwarder_GetFibEntries(mapme->forwarder); - for (size_t i = 0; i < fibEntryList_Length(fiblist); i++) { - FibEntry *fibEntry = (FibEntry *)fibEntryList_Get(fiblist, i); - const Name *name = fibEntry_GetPrefix(fibEntry); - - /* Skip entries that have no local connection as next hop */ - if (!mapme_hasLocalNextHops(mapme, fibEntry)) - continue; - - /* This entry corresponds to a locally served prefix, set - * Special Interest */ - if (!TFIB(fibEntry)) /* Create TFIB associated to FIB entry */ - mapme_CreateTFIB(fibEntry); - TFIB(fibEntry)->seq++; - - char *name_str = name_ToString(name); - INFO(mapme, "[MAP-Me] sending IU/IN for name %s on connection %d", name_str, - conn_added_id); - free(name_str); - - mapme_setFacePending(mapme, name, fibEntry, conn_added_id, true, true, 0); - } - break; +void +mapme_onConnectionEvent(const MapMe *mapme, const Connection *conn_added, connection_event_t event) { + /* Does the priority change impacts the default route selection; if so, + * advertise the prefix on this default route. If there are many default + * routes, either v4 v6, or many connections as next hops on this default + * route, then send to all. + */ + if (conn_added) { + if (connection_IsLocal(conn_added)) + return; + + unsigned conn_added_id = connection_GetConnectionId(conn_added); + switch(event) { + case CONNECTION_EVENT_CREATE: + INFO(mapme, "[MAP-Me] Connection %d got created", conn_added_id); + break; + case CONNECTION_EVENT_DELETE: + INFO(mapme, "[MAP-Me] Connection %d got deleted", conn_added_id); + break; + case CONNECTION_EVENT_UPDATE: + INFO(mapme, "[MAP-Me] Connection %d got updated", conn_added_id); + break; + case CONNECTION_EVENT_SET_UP: + INFO(mapme, "[MAP-Me] Connection %d went up", conn_added_id); + break; + case CONNECTION_EVENT_SET_DOWN: + INFO(mapme, "[MAP-Me] Connection %d went down", conn_added_id); + break; + case CONNECTION_EVENT_TAGS_CHANGED: + INFO(mapme, "[MAP-Me] Connection %d changed tags", conn_added_id); + break; + case CONNECTION_EVENT_PRIORITY_CHANGED: + INFO(mapme, "[MAP-Me] Connection %d changed priority to %d", + conn_added_id, connection_GetPriority(conn_added)); + break; } - case CONNECTION_EVENT_DELETE: - case CONNECTION_EVENT_SET_DOWN: - case CONNECTION_EVENT_UPDATE: - case CONNECTION_EVENT_PRIORITY_CHANGED: - break; } + + /* We need to send a MapMe update on the newly selected connections for + * each concerned fibEntry : connection is involved, or no more involved */ + FibEntryList *fiblist = forwarder_GetFibEntries(mapme->forwarder); + + /* Iterate a first time on the FIB to get the locally served prefixes */ + for (size_t i = 0; i < fibEntryList_Length(fiblist); i++) { + FibEntry *fibEntry = (FibEntry *)fibEntryList_Get(fiblist, i); + mapme_reconsiderFibEntry(mapme, fibEntry); + } + INFO(mapme, "[MAP-Me] Done"); } +#if 0 #ifdef WITH_POLICY void mapme_onPolicyUpdate(const MapMe *mapme, const Connection *conn_selected, FibEntry * fibEntry) { @@ -520,9 +597,10 @@ void mapme_onPolicyUpdate(const MapMe *mapme, const Connection *conn_selected, F conn_selected_id); free(name_str); - mapme_setFacePending(mapme, name, fibEntry, conn_selected_id, true, true, 0); + mapme_setFacePending(mapme, name, fibEntry, conn_selected_id, true, true, true, 0); } #endif /* WITH_POLICY */ +#endif /*------------------------------------------------------------------------------ * Special Interest handling @@ -615,6 +693,19 @@ static bool mapme_onSpecialInterest(const MapMe *mapme, mapme_CreateTFIB(fibEntry); } + /* + * In case of multihoming, we might receive a message about our own prefix, we + * should never take it into account, nor send the IU backwards as a sign of + * outdated propagation. + * + * Detection: we receive a message initially sent by ourselves, ie a message + * for which the prefix has a local next hop in the FIB. + */ + if (mapme_hasLocalNextHops(mapme, fibEntry)) { + INFO(mapme, "[MAP-Me] - Received original interest... Update complete"); + return true; + } + fibSeq = TFIB(fibEntry)->seq; if (seq > fibSeq) { INFO(mapme, @@ -634,7 +725,7 @@ static bool mapme_onSpecialInterest(const MapMe *mapme, INFO(mapme, "[MAP-Me] - Re-sending IU to pending connection %d", conn_id); mapme_setFacePending(mapme, fibEntry_GetPrefix(fibEntry), fibEntry, - conn_id, false, false, 0); + conn_id, false, false, false, 0); } parcIterator_Release(&iterator); } @@ -675,8 +766,8 @@ static bool mapme_onSpecialInterest(const MapMe *mapme, */ INFO(mapme, "[MAP-Me] - Canceled pending timer"); parcEventTimer_Stop(oldTimer); - mapmeTFIB_Remove(TFIB(fibEntry), conn_in_id); } + mapmeTFIB_Remove(TFIB(fibEntry), conn_in_id); /* Remove all next hops */ for (size_t k = 0; k < numberSet_Length(nexthops_old); k++) { @@ -699,7 +790,7 @@ static bool mapme_onSpecialInterest(const MapMe *mapme, INFO(mapme, "[MAP-Me] - Sending IU on current next hop connection %d", conn_id); mapme_setFacePending(mapme, fibEntry_GetPrefix(fibEntry), fibEntry, - conn_id, send, false, 0); + conn_id, send, false, false, 0); complete = false; } @@ -722,10 +813,12 @@ static bool mapme_onSpecialInterest(const MapMe *mapme, * producer and that we received back our own IU. In that case, we just * need to Ack and ignore it. */ +#if 0 if (mapme_hasLocalNextHops(mapme, fibEntry)) { INFO(mapme, "[MAP-Me] - Received original interest... Update complete"); return true; } +#endif INFO(mapme, "[MAP-Me] - Adding multipath next hop on connection %d", conn_in_id); @@ -743,7 +836,7 @@ static bool mapme_onSpecialInterest(const MapMe *mapme, "[MAP-Me] - Update interest %d -> %d sent backwards on connection %d", seq, fibSeq, conn_in_id); mapme_setFacePending(mapme, fibEntry_GetPrefix(fibEntry), fibEntry, - conn_in_id, send, false, 0); + conn_in_id, send, false, false, 0); } return true; @@ -781,6 +874,14 @@ void mapme_onSpecialInterestAck(const MapMe *mapme, const uint8_t *msgBuffer, seq_t fibSeq = TFIB(fibEntry)->seq; if (seq < fibSeq) { + + /* If we receive an old ack: + * - either the connection is still a next hop and we have to ignore + * the ack until we receive a further update with higher seqno + * - or the connection is no more to be informed and the ack is + * sufficient and we can remove future retransmissions + */ + INFO(mapme, "[MAP-Me] - Ignored special interest Ack with seq=%u, expected %u", seq, fibSeq); diff --git a/hicn-light/src/hicn/core/mapme.h b/hicn-light/src/hicn/core/mapme.h index 5888ccd21..81977ab2e 100644 --- a/hicn-light/src/hicn/core/mapme.h +++ b/hicn-light/src/hicn/core/mapme.h @@ -68,6 +68,14 @@ bool mapme_isMapMe(const uint8_t *msgBuffer); void mapme_Process(const MapMe *mapme, const uint8_t *msgBuffer, unsigned conn_id); +/** + * @function mapme_reconsiderFibEntry + * @abstract Process a fib entry for changes that might trigger new updates + * @param [in] mapme - Pointer to the MAP-Me data structure. + * @param [in] fibEntry - The FIB entry to consider + */ +void mapme_reconsiderFibEntry(const MapMe *mapme, FibEntry * fibEntry); + /** * @function mapme_onConnectionEvent * @abstract Callback following the addition of the face though the control @@ -79,14 +87,6 @@ void mapme_Process(const MapMe *mapme, const uint8_t *msgBuffer, */ void mapme_onConnectionEvent(const MapMe *mapme, const Connection *conn, connection_event_t event); -#ifdef WITH_POLICY - -/** - * @function mapme_onPolicyUpdate - */ -void mapme_onPolicyUpdate(const MapMe *mapme, const Connection *conn_added, FibEntry * fibEntry); -#endif /* WITH_POLICY */ - /** * @function mapme_getNextHops * @abstract return the nexthops to forward interests defined by mapme, it diff --git a/hicn-light/src/hicn/core/name.c b/hicn-light/src/hicn/core/name.c index 76efa6a8e..805e7bfae 100644 --- a/hicn-light/src/hicn/core/name.c +++ b/hicn-light/src/hicn/core/name.c @@ -256,4 +256,8 @@ void name_setLen(Name *name, uint8_t len) { uint32_t name_GetSuffix(const Name * name) { return name->segment; } + +uint8_t name_GetLen(const Name * name) { + return nameBitvector_GetLength(name->content_name); +} #endif /* WITH_POLICY */ diff --git a/hicn-light/src/hicn/core/name.h b/hicn-light/src/hicn/core/name.h index 29c8439f8..db9438150 100644 --- a/hicn-light/src/hicn/core/name.h +++ b/hicn-light/src/hicn/core/name.h @@ -98,6 +98,7 @@ Name *name_CreateFromAddress(address_type addressType, ip_address_t addr, #ifdef WITH_POLICY uint32_t name_GetSuffix(const Name * name); +uint8_t name_GetLen(const Name * name); #endif /* WITH_POLICY */ #endif // name_h diff --git a/hicn-light/src/hicn/processor/fibEntry.c b/hicn-light/src/hicn/processor/fibEntry.c index 11a572c88..46917a9d2 100644 --- a/hicn-light/src/hicn/processor/fibEntry.c +++ b/hicn-light/src/hicn/processor/fibEntry.c @@ -61,10 +61,10 @@ struct fib_entry { // NumberSet *available_nexthops; #ifdef WITH_MAPME /* In case of no multipath, this stores the previous decision taken by policy */ - unsigned previous_nexthop; #endif /* WITH_MAPME */ #endif /* WITH_POLICY */ #ifdef WITH_MAPME + NumberSet * previous_nexthops; void *userData; void (*userDataRelease)(void **userData); #endif /* WITH_MAPME */ @@ -122,9 +122,6 @@ FibEntry *fibEntry_Create(Name *name, strategy_type fwdStrategy) { fibEntry->forwarder = forwarder; fibEntry->policy = POLICY_NONE; fibEntry->policy_counters = POLICY_COUNTERS_NONE; -#ifdef WITH_MAPME - fibEntry->previous_nexthop = ~0; -#endif /* WITH_MAPME */ #endif /* WITH_POLICY */ return fibEntry; @@ -223,12 +220,12 @@ fibEntry_GetAvailableNextHops(const FibEntry *fibEntry, unsigned in_connection) ConnectionList * list = connectionTable_GetEntries(table); for (size_t i = 0; i < connectionList_Length(list); i++) { Connection *conn = connectionList_Get(list, i); + if (connection_IsLocal(conn)) + continue; if (connection_GetAdminState(conn) == CONNECTION_STATE_DOWN) continue; if (connection_GetState(conn) == CONNECTION_STATE_DOWN) continue; - if (connection_IsLocal(conn)) - continue; numberSet_Add(nexthops, connection_GetConnectionId(conn)); } connectionList_Destroy(&list); @@ -445,46 +442,57 @@ fibEntry_GetAvailableNextHops(const FibEntry *fibEntry, unsigned in_connection) numberSet_Release(&filtered_nexthops); } - return available_nexthops; -} + /* Priority */ + NumberSet * priority_nexthops = numberSet_Create(); -policy_t fibEntry_GetPolicy(const FibEntry *fibEntry) { - return fibEntry->policy; -} - -void fibEntry_ReconsiderPolicy(FibEntry *fibEntry) { -#ifdef WITH_MAPME - NumberSet * available_nexthops = fibEntry_GetAvailableNextHops(fibEntry, ~0); - - if (numberSet_Length(available_nexthops) == 0) - goto END; - - /* Multipath */ - if ((fibEntry->policy.tags[POLICY_TAG_MULTIPATH].state != POLICY_STATE_PROHIBIT) && - (fibEntry->policy.tags[POLICY_TAG_MULTIPATH].state != POLICY_STATE_AVOID)) - goto END; - - unsigned nexthop = numberSet_GetItem(available_nexthops, 0); - if (nexthop != fibEntry->previous_nexthop) { - /* Policy has elected a new nexthop, signal it using MAP-Me */ - fibEntry->previous_nexthop = nexthop; - ConnectionTable * table = forwarder_GetConnectionTable(fibEntry->forwarder); - const Connection * conn = connectionTable_FindById(table, nexthop); - mapme_onPolicyUpdate(forwarder_getMapmeInstance(fibEntry->forwarder), conn, fibEntry); + uint32_t max_priority = 0; + for (size_t k = 0; k < numberSet_Length(available_nexthops); k++) { + unsigned conn_id = numberSet_GetItem(available_nexthops, k); + const Connection * conn = connectionTable_FindById(table, conn_id); + uint32_t priority = connection_GetPriority(conn); + if (priority < max_priority) { + continue; + } else if (priority == max_priority) { + numberSet_Add(priority_nexthops, conn_id); + } else { /* priority > max_priority */ + numberSet_Release(&priority_nexthops); + priority_nexthops = numberSet_Create(); + numberSet_Add(priority_nexthops, conn_id); + max_priority = priority; + } } -END: numberSet_Release(&available_nexthops); -#endif /* WITH_MAPME */ + + return priority_nexthops; +} + +policy_t fibEntry_GetPolicy(const FibEntry *fibEntry) { + return fibEntry->policy; } void fibEntry_SetPolicy(FibEntry *fibEntry, policy_t policy) { fibEntry->policy = policy; - fibEntry_ReconsiderPolicy(fibEntry); + mapme_reconsiderFibEntry(forwarder_getMapmeInstance(fibEntry->forwarder), fibEntry); } +NumberSet * +fibEntry_GetPreviousNextHops(const FibEntry *fibEntry) +{ + return fibEntry->previous_nexthops; +} #endif /* WITH_POLICY */ +void +fibEntry_SetPreviousNextHops(FibEntry *fibEntry, NumberSet * nexthops) +{ + if (fibEntry->previous_nexthops) + numberSet_Release(&fibEntry->previous_nexthops); + fibEntry->previous_nexthops = numberSet_Create(); + numberSet_AddSet(fibEntry->previous_nexthops, nexthops); +} + + void fibEntry_AddNexthop(FibEntry *fibEntry, unsigned connectionId) { parcAssertNotNull(fibEntry, "Parameter fibEntry must be non-null"); #ifdef WITH_POLICY @@ -576,39 +584,16 @@ const NumberSet *fibEntry_GetNexthopsFromForwardingStrategy( if (numberSet_Length(available_nexthops) == 0) { out = numberSet_Create(); } else { - - /* Priority */ - NumberSet * priority_nexthops = numberSet_Create(); - - uint32_t max_priority = 0; - for (size_t k = 0; k < numberSet_Length(available_nexthops); k++) { - unsigned conn_id = numberSet_GetItem(available_nexthops, k); - const Connection * conn = connectionTable_FindById(table, conn_id); - uint32_t priority = connection_GetPriority(conn); - if (priority < max_priority) { - continue; - } else if (priority == max_priority) { - numberSet_Add(priority_nexthops, conn_id); - } else { /* priority > max_priority */ - numberSet_Release(&priority_nexthops); - priority_nexthops = numberSet_Create(); - numberSet_Add(priority_nexthops, conn_id); - max_priority = priority; - } - } - /* Multipath */ if ((policy.tags[POLICY_TAG_MULTIPATH].state != POLICY_STATE_PROHIBIT) && (policy.tags[POLICY_TAG_MULTIPATH].state != POLICY_STATE_AVOID)) { - out = fibEntry->fwdStrategy->lookupNexthop(fibEntry->fwdStrategy, priority_nexthops, + out = fibEntry->fwdStrategy->lookupNexthop(fibEntry->fwdStrategy, available_nexthops, interestMessage); } else { - unsigned nexthop = numberSet_GetItem(priority_nexthops, 0); + unsigned nexthop = numberSet_GetItem(available_nexthops, 0); out = numberSet_Create(); numberSet_Add(out, nexthop); } - - numberSet_Release(&priority_nexthops); } numberSet_Release(&available_nexthops); diff --git a/hicn-light/src/hicn/processor/fibEntry.h b/hicn-light/src/hicn/processor/fibEntry.h index 11a00e836..7ec771b4c 100644 --- a/hicn-light/src/hicn/processor/fibEntry.h +++ b/hicn-light/src/hicn/processor/fibEntry.h @@ -81,16 +81,6 @@ FibEntry *fibEntry_Acquire(const FibEntry *fibEntry); void fibEntry_SetStrategy(FibEntry *fibEntry, strategy_type strategy); -#ifdef WITH_POLICY - -policy_t fibEntry_GetPolicy(const FibEntry *fibEntry); - -void fibEntry_ReconsiderPolicy(FibEntry *fibEntry); - -void fibEntry_SetPolicy(FibEntry *fibEntry, policy_t policy); - -#endif /* WITH_POLICY */ - void fibEntry_AddNexthop(FibEntry *fibEntry, unsigned connectionId); void fibEntry_RemoveNexthopByConnectionId(FibEntry *fibEntry, @@ -123,14 +113,30 @@ void fibEntry_ReceiveObjectMessage(const FibEntry *fibEntry, const Message *objectMessage, Ticks rtt); #ifdef WITH_POLICY +policy_t fibEntry_GetPolicy(const FibEntry *fibEntry); +void fibEntry_ReconsiderPolicy(FibEntry *fibEntry); +void fibEntry_SetPolicy(FibEntry *fibEntry, policy_t policy); +void fibEntry_UpdateStats(FibEntry *fibEntry, uint64_t now); +NumberSet * fibEntry_GetAvailableNextHops(const FibEntry *fibEntry, unsigned in_connection); +NumberSet * fibEntry_GetPreviousNextHops(const FibEntry *fibEntry); +void fibEntry_SetPreviousNextHops(FibEntry *fibEntry, NumberSet * nexthops); + void fibEntry_OnTimeout(FibEntry *fibEntry, const NumberSet *egressId); +const NumberSet *fibEntry_GetNexthopsFromForwardingStrategy( + FibEntry *fibEntry, const Message *interestMessage, bool is_retransmission); + +void fibEntry_ReceiveObjectMessage(FibEntry *fibEntry, + const NumberSet *egressId, + const Message *objectMessage, Ticks rtt); #else void fibEntry_OnTimeout(const FibEntry *fibEntry, const NumberSet *egressId); +const NumberSet *fibEntry_GetNexthopsFromForwardingStrategy( + const FibEntry *fibEntry, const Message *interestMessage); +void fibEntry_ReceiveObjectMessage(const FibEntry *fibEntry, + const NumberSet *egressId, + const Message *objectMessage, Ticks rtt); #endif /* WITH_POLICY */ -#ifdef WITH_POLICY -void fibEntry_UpdateStats(FibEntry *fibEntry, uint64_t now); -#endif /* WITH_POLICY */ strategy_type fibEntry_GetFwdStrategyType(const FibEntry *fibEntry); diff --git a/hicn-light/src/hicn/processor/messageProcessor.c b/hicn-light/src/hicn/processor/messageProcessor.c index 58220ac9c..ad9a4e6ac 100644 --- a/hicn-light/src/hicn/processor/messageProcessor.c +++ b/hicn-light/src/hicn/processor/messageProcessor.c @@ -393,21 +393,6 @@ bool messageProcessor_RemovePolicy(MessageProcessor *processor, return true; } - -#ifdef WITH_MAPME -void messageProcessor_onConnectionEvent(const MessageProcessor *processor, - const Connection *conn_added, connection_event_t event) -{ - FibEntryList *fiblist = forwarder_GetFibEntries(processor->forwarder); - for (size_t i = 0; i < fibEntryList_Length(fiblist); i++) { - FibEntry *fibEntry = (FibEntry *)fibEntryList_Get(fiblist, i); - fibEntry_ReconsiderPolicy(fibEntry); - } - fibEntryList_Destroy(&fiblist); - -} -#endif /* WITH_MAPME */ - #endif /* WITH_POLICY */ void messageProcessor_RemoveConnectionIdFromRoutes(MessageProcessor *processor, diff --git a/hicn-light/src/hicn/processor/messageProcessor.h b/hicn-light/src/hicn/processor/messageProcessor.h index 6804ba018..80cd22035 100644 --- a/hicn-light/src/hicn/processor/messageProcessor.h +++ b/hicn-light/src/hicn/processor/messageProcessor.h @@ -136,11 +136,6 @@ bool messageProcessor_AddOrUpdatePolicy(MessageProcessor *processor, bool messageProcessor_RemovePolicy(MessageProcessor *processor, remove_policy_command *control); -#ifdef WITH_MAPME -void messageProcessor_onConnectionEvent(const MessageProcessor *processor, - const Connection *conn_added, connection_event_t event); -#endif /* WITH_MAPME */ - #endif /* WITH_POLICY */ /** diff --git a/hicn-light/src/hicn/utils/commands.h b/hicn-light/src/hicn/utils/commands.h index c250216f0..bb566e688 100644 --- a/hicn-light/src/hicn/utils/commands.h +++ b/hicn-light/src/hicn/utils/commands.h @@ -76,6 +76,7 @@ typedef enum { REMOVE_POLICY, UPDATE_CONNECTION, CONNECTION_SET_PRIORITY, + CONNECTION_SET_TAGS, #endif /* WITH_POLICY */ LAST_COMMAND_VALUE } command_id; @@ -345,6 +346,11 @@ typedef struct { uint32_t priority; } connection_set_priority_command; +typedef struct { + char symbolicOrConnid[SYMBOLIC_NAME_LEN]; + policy_tags_t tags; +} connection_set_tags_command; + #endif /* WITH_POLICY */ //===== size of commands ====== @@ -403,6 +409,8 @@ static inline int payloadLengthDaemon(command_id id) { return sizeof(update_connection_command); case CONNECTION_SET_PRIORITY: return sizeof(connection_set_priority_command); + case CONNECTION_SET_TAGS: + return sizeof(connection_set_tags_command); #endif /* WITH_POLICY */ case LAST_COMMAND_VALUE: return 0; -- cgit 1.2.3-korg