summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJordan Augé <jordan.auge+fdio@cisco.com>2019-12-11 15:08:48 +0100
committerJordan Augé <jordan.auge+fdio@cisco.com>2019-12-11 15:08:48 +0100
commitba89f69b00b052298c8689c4f0d62b4429f96516 (patch)
tree58532131bd779404e1ec57ae7bd6949b23b37401
parent2f8f60f943b71e1caab14856c6a03c81e5ba6c9c (diff)
[HICN-446] Face manager incorrectly sets up static routes in case of multihoming during startup
Change-Id: Iee01146d3d9437f0267cfac3de793608cccca5bc Signed-off-by: Jordan Augé <jordan.auge+fdio@cisco.com>
-rw-r--r--ctrl/facemgr/src/api.c182
-rw-r--r--ctrl/facemgr/src/facelet.c2
2 files changed, 143 insertions, 41 deletions
diff --git a/ctrl/facemgr/src/api.c b/ctrl/facemgr/src/api.c
index ac436a433..4233c469b 100644
--- a/ctrl/facemgr/src/api.c
+++ b/ctrl/facemgr/src/api.c
@@ -97,6 +97,7 @@ extern interface_ops_t updown_ops;
#endif
extern interface_ops_t hicn_light_ops;
+int facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet);
int
facemgr_overlay_snprintf(char * s, size_t size, const facemgr_overlay_t * overlay)
@@ -560,7 +561,8 @@ facelet_cache_lookup(const facelet_set_t * facelet_cache, facelet_t * facelet,
ERROR("[facelet_cache_lookup] Error during cache match");
return -1;
}
- *cached_facelets = malloc(n * sizeof(facelet_t*));
+ if (cached_facelets)
+ *cached_facelets = malloc(n * sizeof(facelet_t*));
int num_match = 0;
for (unsigned i = 0; i < n; i++) {
@@ -572,7 +574,9 @@ facelet_cache_lookup(const facelet_set_t * facelet_cache, facelet_t * facelet,
if (!facelet_match(facelet_array[i], facelet)) {
continue;
}
- (*cached_facelets)[num_match++] = facelet_array[i];
+ if (cached_facelets)
+ (*cached_facelets)[num_match] = facelet_array[i];
+ num_match++;
}
free(facelet_array);
return num_match;
@@ -618,6 +622,13 @@ facemgr_facelet_satisfy_rules(facemgr_t * facemgr, facelet_t * facelet)
}
#endif /* WITH_ANDROID_UTILITY */
+ /* Default ignore list */
+ if ((netdevice_type == NETDEVICE_TYPE_LOOPBACK) || (netdevice_type == NETDEVICE_TYPE_UNDEFINED)) {
+ DEBUG("Ignored interface '%s/%s'...", netdevice.name,
+ netdevice_type_str[netdevice_type]);
+ return -3;
+ }
+
/* Ignore */
bool ignore;
if (facemgr_cfg_get_ignore(facemgr->cfg, &netdevice, netdevice_type,
@@ -912,6 +923,7 @@ facemgr_complement_facelet(facemgr_t * facemgr, facelet_t * facelet)
{
int rc;
+ DEBUG("[facemgr_complement_facelet]");
if (!facelet_has_key(facelet))
return -2;
@@ -944,7 +956,7 @@ facemgr_complement_facelet(facemgr_t * facemgr, facelet_t * facelet)
return rc;
#endif /* __linux__ */
- DEBUG("Complement manual");
+ DEBUG("[facemgr_complement_facelet] Complement manual");
rc = facemgr_complement_facelet_manual(facemgr, facelet);
if (rc != -2)
@@ -1011,11 +1023,12 @@ facemgr_process_facelet(facemgr_t * facemgr, facelet_t * facelet)
switch(rc) {
case -3:
/* Does not satisfy rules */
+ DEBUG("[facemgr_process_facelet] Does not satisfy rules");
facelet_set_status(facelet, FACELET_STATUS_IGNORED);
return 0;
case -2:
- /* Not enough information: AU in fact */
+ DEBUG("[facemgr_process_facelet] Complementing facelet is required");
if (facemgr_complement_facelet(facemgr, facelet) < 0) {
ERROR("[facemgr_process_facelet] Error while attempting to complement face for fields required by face creation");
goto ERR;
@@ -1088,7 +1101,6 @@ facemgr_process_facelet(facemgr_t * facemgr, facelet_t * facelet)
goto ERR;
}
- /* Facelets created from static get deleted */
#if 0
if (facelet_get_id(facelet) > 0) {
if (facelet_set_remove(facemgr->facelet_cache, facelet, NULL) < 0) {
@@ -1102,12 +1114,15 @@ facemgr_process_facelet(facemgr_t * facemgr, facelet_t * facelet)
DEBUG("[facemgr_process_facelet] Cleaning cached data");
facelet_unset_local_addr(facelet);
facelet_unset_local_port(facelet);
- facelet_unset_remote_addr(facelet);
- facelet_unset_remote_port(facelet);
+ if (facelet_get_id(facelet) == 0) {
+ facelet_unset_remote_addr(facelet);
+ facelet_unset_remote_port(facelet);
+ facelet_clear_routes(facelet);
+ }
+
facelet_unset_admin_state(facelet);
facelet_unset_state(facelet);
facelet_unset_bj_done(facelet);
- facelet_clear_routes(facelet);
#ifdef WITH_ANDROID_UTILITY
facelet_unset_au_done(facelet);
#endif /* WITH_ANDROID_UTILITY */
@@ -1329,7 +1344,10 @@ facemgr_consider_static_facelet(facemgr_t * facemgr, facelet_t * facelet)
if (facelet_found)
return 0;
- facelet_set_id(static_facelet, ++facemgr->cur_static_id);
+ facemgr->cur_static_id++;
+
+ facelet_set_id(static_facelet, facemgr->cur_static_id);
+ facelet_set_id(facelet, facemgr->cur_static_id);
if (facelet_array_add(facemgr->static_facelets, static_facelet) < 0) {
ERROR("[facemgr_consider_static_facelet] Could not add facelet to static array");
@@ -1345,6 +1363,78 @@ facemgr_consider_static_facelet(facemgr_t * facemgr, facelet_t * facelet)
ERROR("[facemgr_consider_static_facelet] Error during facelet string output");
DEBUG("[facemgr_consider_static_facelet] Successfully added facelet to static array %s", facelet_s);
+#if 1
+ /* Force application of the static face on all existing interfaces */
+ facelet_t ** facelet_array;
+ int n = facelet_set_get_array(facemgr->facelet_cache, &facelet_array);
+ if (n >= 0) {
+ for (unsigned i = 0; i < n; i++) {
+ facelet_t * cached_facelet = facelet_array[i];
+
+ netdevice_type_t netdevice_type;
+ if (facelet_get_netdevice_type(facelet, &netdevice_type) < 0) {
+ ERROR("[facemgr_consider_static_facelet] Error retrieving netdevice type from cached facelet");
+ continue;
+ }
+ if ((netdevice_type == NETDEVICE_TYPE_LOOPBACK) || (netdevice_type == NETDEVICE_TYPE_UNDEFINED))
+ continue;
+
+ facelet_t * new_facelet = facelet_dup(cached_facelet);
+ facelet_unset_remote_addr(new_facelet);
+ facelet_unset_remote_port(new_facelet);
+ facelet_unset_admin_state(new_facelet);
+ facelet_unset_state(new_facelet);
+ facelet_unset_bj_done(new_facelet);
+ facelet_clear_routes(new_facelet);
+#ifdef WITH_ANDROID_UTILITY
+ facelet_unset_au_done(new_facelet);
+#endif /* WITH_ANDROID_UTILITY */
+
+ /* We try to apply static_facelet over facelet */
+ if (!facelet_match(new_facelet, static_facelet)) {
+ facelet_free(new_facelet);
+ continue;
+ }
+
+ if (facelet_merge(new_facelet, static_facelet) < 0) {
+ ERROR("[facemgr_consider_static_facelet] Error merging facelets");
+ facelet_free(new_facelet);
+ continue;
+ }
+
+ /*
+ * We need to set the id before checking for existence as tuple used
+ * is (id, netdevice, family)
+ */
+ facelet_set_id(new_facelet, facemgr->cur_static_id);
+
+ facelet_found = NULL;
+ if (facelet_set_get(facemgr->facelet_cache, new_facelet, &facelet_found) < 0) {
+ ERROR("[facemgr_consider_static_facelet] Error checking whether new static facelet already exists or not");
+ continue;
+ }
+
+
+ /* Skip addition if facelet exists */
+ if (facelet_found) {
+ facelet_free(new_facelet);
+ continue;
+ }
+
+ facelet_set_attr_clean(new_facelet);
+ facelet_set_status(facelet, FACELET_STATUS_UNDEFINED);
+
+ if (facemgr_on_event(facemgr, new_facelet) < 0) {
+ ERROR("[facemgr_process_facelet_create_no_family] Error creating static facelet for existing face");
+ continue;
+ }
+
+ INFO("Successfully created static facelet for existing face");
+ }
+ free(facelet_array);
+ }
+#endif
+
return 1;
}
@@ -1368,8 +1458,19 @@ facemgr_process_facelet_get(facemgr_t * facemgr, facelet_t * facelet)
return -1;
if (!IS_VALID_NETDEVICE(netdevice))
return -2;
+
facelet_set_status(facelet, FACELET_STATUS_CLEAN);
+ /* Skip if face exists */
+ int n = facelet_cache_lookup(facemgr->facelet_cache, facelet, NULL);
+ if (n < 0) {
+ ERROR("[facemgr_process_facelet_get] Error during cache lookup");
+ return -1;
+ }
+ assert (n <= 1);
+ if (n > 0)
+ return 0;
+
/* Process untagged faces */
netdevice_type_t netdevice_type;
if (facelet_get_netdevice_type(facelet, &netdevice_type) < 0) {
@@ -1405,36 +1506,31 @@ facemgr_process_facelet_get(facemgr_t * facemgr, facelet_t * facelet)
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");
- return -1;
- }
- if (n == 1) {
- /*
- * As a static facelet, it receives a new id not to be confused in the
- * cache with default facelets
- */
- facelet_set_id(facelet, ++facemgr->cur_static_id);
+ if ((netdevice_type == NETDEVICE_TYPE_UNDEFINED) || (netdevice_type == NETDEVICE_TYPE_LOOPBACK))
+ return 0;
+
+ if (facemgr_process_facelet(facemgr, facelet) < 0) {
+ ERROR("[facemgr_process_facelet_get] Error processing facelet");
+ return -1;
+ }
}
- char facelet_s[MAXSZ_FACELET];
- facelet_snprintf(facelet_s, MAXSZ_FACELET, facelet);
+ if ((netdevice_type == NETDEVICE_TYPE_UNDEFINED) || (netdevice_type == NETDEVICE_TYPE_LOOPBACK))
+ return 0;
+
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;
- }
+ n = facemgr_consider_static_facelet(facemgr, facelet);
+ if (n < 0) {
+ ERROR("[facemgr_process_facelet_get] Could not add facelet to static array");
+ return -1;
}
+
return 0;
}
@@ -1516,12 +1612,14 @@ facemgr_process_facelet_delete(facemgr_t * facemgr, facelet_t * facelet)
DEBUG("[facemgr_process_facelet] Cleaning cached data");
facelet_unset_local_addr(facelet);
facelet_unset_local_port(facelet);
- facelet_unset_remote_addr(facelet);
- facelet_unset_remote_port(facelet);
+ if (facelet_get_id(facelet) == 0) {
+ facelet_unset_remote_addr(facelet);
+ facelet_unset_remote_port(facelet);
+ facelet_clear_routes(facelet);
+ }
facelet_unset_admin_state(facelet);
facelet_unset_state(facelet);
facelet_unset_bj_done(facelet);
- facelet_clear_routes(facelet);
#ifdef WITH_ANDROID_UTILITY
facelet_unset_au_done(facelet);
#endif /* WITH_ANDROID_UTILITY */
@@ -1555,8 +1653,6 @@ facemgr_process_facelet_delete(facemgr_t * facemgr, facelet_t * facelet)
return 0;
}
-int facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet);
-
int
facemgr_process_facelet_create_no_family(facemgr_t * facemgr, facelet_t * facelet)
{
@@ -1624,7 +1720,6 @@ facemgr_process_facelet_create_no_family(facemgr_t * facemgr, facelet_t * facele
continue;
}
facelet_set_id(facelet_new, facelet_get_id(static_facelet));
- /* The id must be different than 0 */
facelet_set_attr_clean(facelet_new);
facelet_set_status(facelet, FACELET_STATUS_UNDEFINED);
@@ -1668,6 +1763,17 @@ facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in)
facelet_set_netdevice_type(facelet_in, facemgr_get_netdevice_type(facemgr, netdevice.name));
}
+#if 0
+ netdevice_type_t netdevice_type;
+ if (facelet_get_netdevice_type(facelet_in, &netdevice_type) < 0) {
+ return 0;
+ }
+
+ if ((netdevice_type == NETDEVICE_TYPE_UNDEFINED) ||
+ (netdevice_type == NETDEVICE_TYPE_LOOPBACK))
+ return 0;
+#endif
+
char facelet_s[MAXSZ_FACELET];
facelet_snprintf(facelet_s, MAXSZ_FACELET, facelet_in);
@@ -1864,12 +1970,6 @@ facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in)
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:
diff --git a/ctrl/facemgr/src/facelet.c b/ctrl/facemgr/src/facelet.c
index ac84f5f70..d33455b4d 100644
--- a/ctrl/facemgr/src/facelet.c
+++ b/ctrl/facemgr/src/facelet.c
@@ -198,6 +198,8 @@ facelet_validate_face(const facelet_t * facelet)
if (!facelet_has_remote_addr(facelet))
return false;
case FACE_TYPE_LAYER_3:
+ if (!facelet_has_local_port(facelet))
+ return false;
if (!facelet_has_local_addr(facelet))
return false;
if (!facelet_has_netdevice(facelet))