aboutsummaryrefslogtreecommitdiffstats
path: root/ctrl
diff options
context:
space:
mode:
authorJordan Augé <jordan.auge+fdio@cisco.com>2019-11-27 09:05:39 +0100
committerJordan Augé <jordan.auge+fdio@cisco.com>2019-12-05 00:32:28 +0100
commit94350c13fe983a7cfb99dafecb0d029ed58361bf (patch)
treeed82fbed47a3ec2b9855e93402b3f75f3f403b57 /ctrl
parentdafa145fb5a4a10c1e600ee72fe639ac4f7e718d (diff)
[HICN-420] MAP-Me code refactoring & face manager changes in support of mobility
Change-Id: Ifde50b4c161d1bda1326f18b705f575e539aea71 Signed-off-by: Jordan Augé <jordan.auge+fdio@cisco.com>
Diffstat (limited to 'ctrl')
-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
14 files changed, 448 insertions, 125 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
*----------------------------------------------------------------------------*/