diff options
Diffstat (limited to 'ctrl')
-rw-r--r-- | ctrl/facemgr/includes/hicn/facemgr/facelet.h | 15 | ||||
-rw-r--r-- | ctrl/facemgr/src/api.c | 326 | ||||
-rw-r--r-- | ctrl/facemgr/src/facelet.c | 51 | ||||
-rw-r--r-- | ctrl/facemgr/src/interface.c | 2 | ||||
-rw-r--r-- | ctrl/facemgr/src/interface.h | 4 | ||||
-rw-r--r-- | ctrl/facemgr/src/interfaces/android_utility/android_utility.c | 2 | ||||
-rw-r--r-- | ctrl/facemgr/src/interfaces/bonjour/bonjour.c | 2 | ||||
-rw-r--r-- | ctrl/facemgr/src/interfaces/dummy/dummy.c | 2 | ||||
-rw-r--r-- | ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c | 71 | ||||
-rw-r--r-- | ctrl/facemgr/src/interfaces/netlink/netlink.c | 27 | ||||
-rw-r--r-- | ctrl/facemgr/src/interfaces/priority_controller/priority_controller.c | 4 | ||||
-rw-r--r-- | ctrl/libhicnctrl/includes/hicn/ctrl/api.h | 2 | ||||
-rw-r--r-- | ctrl/libhicnctrl/includes/hicn/ctrl/commands.h | 8 | ||||
-rw-r--r-- | ctrl/libhicnctrl/src/api.c | 57 | ||||
-rw-r--r-- | ctrl/sysrepo-plugins/CMakeLists.txt | 2 |
15 files changed, 449 insertions, 126 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/ctrl/sysrepo-plugins/CMakeLists.txt b/ctrl/sysrepo-plugins/CMakeLists.txt index 4671794a0..d87319f06 100644 --- a/ctrl/sysrepo-plugins/CMakeLists.txt +++ b/ctrl/sysrepo-plugins/CMakeLists.txt @@ -37,7 +37,7 @@ if (NOT SRPD_PLUGINS_PATH) endif() if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) - find_package(VPP REQUIRED) + find_package(Vpp REQUIRED) find_package(HicnPlugin REQUIRED) find_package(Libhicn REQUIRED) add_subdirectory(hicn-plugin) |