summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ctrl/facemgr/includes/hicn/facemgr/facelet.h15
-rw-r--r--ctrl/facemgr/src/api.c326
-rw-r--r--ctrl/facemgr/src/facelet.c51
-rw-r--r--ctrl/facemgr/src/interface.c2
-rw-r--r--ctrl/facemgr/src/interface.h4
-rw-r--r--ctrl/facemgr/src/interfaces/android_utility/android_utility.c2
-rw-r--r--ctrl/facemgr/src/interfaces/bonjour/bonjour.c2
-rw-r--r--ctrl/facemgr/src/interfaces/dummy/dummy.c2
-rw-r--r--ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c71
-rw-r--r--ctrl/facemgr/src/interfaces/netlink/netlink.c27
-rw-r--r--ctrl/facemgr/src/interfaces/priority_controller/priority_controller.c4
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/api.h2
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/commands.h8
-rw-r--r--ctrl/libhicnctrl/src/api.c57
-rw-r--r--ctrl/sysrepo-plugins/CMakeLists.txt2
-rw-r--r--hicn-light/src/hicn/command_line/controller/hicnLightControl_main.c1
-rw-r--r--hicn-light/src/hicn/config/configuration.c24
-rw-r--r--hicn-light/src/hicn/core/connection.h1
-rw-r--r--hicn-light/src/hicn/core/forwarder.c8
-rw-r--r--hicn-light/src/hicn/core/mapme.c217
-rw-r--r--hicn-light/src/hicn/core/mapme.h16
-rw-r--r--hicn-light/src/hicn/core/name.c4
-rw-r--r--hicn-light/src/hicn/core/name.h1
-rw-r--r--hicn-light/src/hicn/processor/fibEntry.c103
-rw-r--r--hicn-light/src/hicn/processor/fibEntry.h32
-rw-r--r--hicn-light/src/hicn/processor/messageProcessor.c15
-rw-r--r--hicn-light/src/hicn/processor/messageProcessor.h5
-rw-r--r--hicn-light/src/hicn/utils/commands.h8
28 files changed, 722 insertions, 288 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), &params, 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)
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, &params);
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
@@ -69,6 +69,14 @@ 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
* protocol.
@@ -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;