aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ctrl/facemgr/includes/hicn/facemgr/facelet.h46
-rw-r--r--ctrl/facemgr/src/api.c269
-rw-r--r--ctrl/facemgr/src/facelet.c121
-rw-r--r--ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c268
-rw-r--r--ctrl/libhicnctrl/examples/create_face.c3
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/api.h5
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/commands.h13
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/face.h1
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/route.h1
-rw-r--r--ctrl/libhicnctrl/src/api.c85
-rw-r--r--ctrl/libhicnctrl/src/cli.c2
-rw-r--r--ctrl/libhicnctrl/src/face.c1
-rw-r--r--ctrl/libhicnctrl/src/route.c10
-rw-r--r--ctrl/sysrepo-plugins/hicn-plugin/plugin/model/hicn_model.c16
-rw-r--r--hicn-light/src/hicn/command_line/controller/hicnLightControl_main.c1
-rw-r--r--hicn-light/src/hicn/config/configuration.c36
-rw-r--r--hicn-light/src/hicn/config/controlListConnections.c5
-rw-r--r--hicn-light/src/hicn/core/connection.c20
-rw-r--r--hicn-light/src/hicn/core/connection.h7
-rw-r--r--hicn-light/src/hicn/core/mapme.c1
-rw-r--r--hicn-light/src/hicn/io/hicnConnection.c31
-rw-r--r--hicn-light/src/hicn/io/ioOperations.c10
-rw-r--r--hicn-light/src/hicn/io/ioOperations.h23
-rw-r--r--hicn-light/src/hicn/io/streamConnection.c31
-rw-r--r--hicn-light/src/hicn/io/udpConnection.c31
-rw-r--r--hicn-light/src/hicn/processor/fibEntry.c27
-rw-r--r--hicn-light/src/hicn/utils/commands.h13
-rw-r--r--hicn-plugin/src/error.h2
-rw-r--r--hicn-plugin/src/faces/udp/face_udp.c2
-rw-r--r--hicn-plugin/src/hicn.api187
-rw-r--r--hicn-plugin/src/hicn_api.c314
-rw-r--r--hicn-plugin/src/hicn_api_test.c510
-rw-r--r--lib/includes/hicn/util/array.h3
-rw-r--r--lib/includes/hicn/util/set.h6
34 files changed, 1807 insertions, 294 deletions
diff --git a/ctrl/facemgr/includes/hicn/facemgr/facelet.h b/ctrl/facemgr/includes/hicn/facemgr/facelet.h
index 476858eff..a0318b206 100644
--- a/ctrl/facemgr/includes/hicn/facemgr/facelet.h
+++ b/ctrl/facemgr/includes/hicn/facemgr/facelet.h
@@ -33,6 +33,8 @@
#define MAXSZ_FACELET 1024
+#define FACELET_MAX_ERRORS 10
+
/* NOTE: Any test should be sufficient */
#define IS_VALID_NETDEVICE(netdevice) ((netdevice.index != 0) && (netdevice.name[0] != '\0'))
@@ -116,6 +118,23 @@ typedef enum {
extern const char * facelet_status_str[];
+/* Facelet error reason */
+#define foreach_facelet_error_reason \
+ _(UNDEFINED) \
+ _(UNSPECIFIED_ERROR) \
+ _(FORWARDER_OFFLINE) \
+ _(PERMISSION_DENIED) \
+ _(INTERNAL_ERROR) \
+ _(N)
+
+typedef enum {
+#define _(x) FACELET_ERROR_REASON_ ## x,
+ foreach_facelet_error_reason
+#undef _
+} facelet_error_reason_t;
+
+extern const char * facelet_error_reason_str[];
+
/* Facelet attribute status */
/*
@@ -142,6 +161,20 @@ extern const char * facelet_attr_status_str_short[];
/* Facelet attribute */
+#ifdef WITH_POLICY
+#define foreach_facelet_attr \
+ _(netdevice_type_t, netdevice_type) \
+ _(netdevice_t, netdevice) \
+ _(int, family) \
+ _(ip_address_t, local_addr) \
+ _(u16, local_port) \
+ _(ip_address_t, remote_addr) \
+ _(u16, remote_port) \
+ _(face_state_t, admin_state) \
+ _(face_state_t, state) \
+ _(u32, priority) \
+ _(facemgr_face_type_t, face_type)
+#else
#define foreach_facelet_attr \
_(netdevice_type_t, netdevice_type) \
_(netdevice_t, netdevice) \
@@ -153,6 +186,7 @@ extern const char * facelet_attr_status_str_short[];
_(face_state_t, admin_state) \
_(face_state_t, state) \
_(facemgr_face_type_t, face_type)
+#endif /* WITH_POLICY */
#define foreach_facelet_event \
_(UNDEFINED) \
@@ -160,13 +194,6 @@ extern const char * facelet_attr_status_str_short[];
_(CREATE) \
_(UPDATE) \
_(DELETE) \
- _(SET_PARAMS) \
- _(SET_UP) \
- _(SET_DOWN) \
- _(SET_TAGS) \
- _(CLEAR_TAGS) \
- _(ADD_TAG) \
- _(REMOVE_TAG) \
_(N)
#define MAXSZ_EVENT__ 10
@@ -234,8 +261,9 @@ int facelet_merge(facelet_t * facelet, const 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);
-void facelet_set_status_error(facelet_t * facelet, bool value);
-bool facelet_get_status_error(const facelet_t * facelet);
+void facelet_set_error(facelet_t * facelet, facelet_error_reason_t reason);
+void facelet_unset_error(facelet_t * facelet);
+bool facelet_get_error(const facelet_t * facelet);
void facelet_set_bj_done(facelet_t * facelet);
void facelet_unset_bj_done(facelet_t * facelet);
diff --git a/ctrl/facemgr/src/api.c b/ctrl/facemgr/src/api.c
index 23ca2f2ae..dfb23db3b 100644
--- a/ctrl/facemgr/src/api.c
+++ b/ctrl/facemgr/src/api.c
@@ -160,6 +160,8 @@ struct facemgr_s {
interface_t * updown;
#endif
int timer_fd; /* Timer used for reattempts */
+
+ int cur_static_id; /* Used to distinguish static faces (pre-incremented) */
};
int
@@ -198,6 +200,7 @@ facemgr_initialize(facemgr_t * facemgr)
}
facemgr->timer_fd = 0;
+ facemgr->cur_static_id = 0;
return 0;
@@ -417,11 +420,13 @@ facemgr_create_interface(facemgr_t * facemgr, const char * name, const char * ty
*pinterface = interface;
return 0;
+
+ //interface_finalize(interface);
+ERR_INIT:
+ interface_map_remove(facemgr->interface_map, interface->name, NULL);
ERR_MAP_ADD:
free(interface_map_data);
ERR_MAP_DATA:
- interface_finalize(interface);
-ERR_INIT:
interface_free(interface);
ERR_CREATE:
if (pinterface)
@@ -489,6 +494,7 @@ int facemgr_query_bonjour(facemgr_t * facemgr, netdevice_t * netdevice)
DEBUG("sending event to bonjour interface");
/* Send an event to the interface (GET ?) */
+ // XXX error handling
return interface_on_event(bj, NULL);
}
#endif /* __linux__ */
@@ -506,8 +512,10 @@ int facemgr_query_android_utility(facemgr_t * facemgr, netdevice_t netdevice)
goto ERR_ND;
rc = interface_on_event(facemgr->au, facelet);
- if (rc < 0)
+ if (rc < 0) {
+ // XXX error handling
goto ERR_EVENT;
+ }
return 0;
@@ -533,6 +541,9 @@ int
facelet_cache_lookup(const facelet_set_t * facelet_cache, facelet_t * facelet,
facelet_t ***cached_facelets)
{
+ assert(facelet);
+ if (!facelet_has_family(facelet))
+ return 0;
#if 0 // key is no more sufficient now that we support multiple faces per interface
/*
* If the facelet is uniquely identified by its key, it is used to perform
@@ -565,6 +576,11 @@ facelet_cache_lookup(const facelet_set_t * facelet_cache, facelet_t * facelet,
int num_match = 0;
for (unsigned i = 0; i < n; i++) {
+#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);
+#endif
if (!facelet_match(facelet_array[i], facelet)) {
continue;
}
@@ -679,6 +695,7 @@ facemgr_complement_facelet_au(facemgr_t * facemgr, facelet_t * facelet)
return -2;
netdevice_t netdevice = NETDEVICE_EMPTY;
+
int rc = facelet_get_netdevice(facelet, &netdevice);
if (rc < 0) {
ERROR("[facemgr_complement_facelet_bj] Error retrieving netdevice from facelet");
@@ -955,7 +972,7 @@ int facemgr_assign_face_type(facemgr_t * facemgr, facelet_t * facelet)
netdevice_t netdevice = NETDEVICE_EMPTY;
int rc = facelet_get_netdevice(facelet, &netdevice);
if (rc < 0) {
- ERROR("[facemgr_facelet_satisfy_rules] Error retrieving netdevice from facelet");
+ ERROR("[facemgr_assign_face_type] Error retrieving netdevice from facelet");
return -1;
}
@@ -967,7 +984,7 @@ int facemgr_assign_face_type(facemgr_t * facemgr, facelet_t * facelet)
*/
rc = facelet_get_netdevice_type(facelet, &netdevice_type);
if (rc < 0) {
- ERROR("[facemgr_facelet_satisfy_rules] Error retrieving netdevice_type from facelet");
+ ERROR("[facemgr_assign_face_type] Error retrieving netdevice_type from facelet");
return -2;
}
#endif /* WITH_ANDROID_UTILITY */
@@ -989,6 +1006,7 @@ int
facemgr_process_facelet(facemgr_t * facemgr, facelet_t * facelet)
{
int rc;
+ facelet_error_reason_t reason = FACELET_ERROR_REASON_INTERNAL_ERROR;
switch(facelet_get_status(facelet)) {
case FACELET_STATUS_UNCERTAIN:
@@ -1046,8 +1064,10 @@ facemgr_process_facelet(facemgr_t * facemgr, facelet_t * facelet)
case FACELET_STATUS_CREATE:
facelet_set_event(facelet, FACELET_EVENT_CREATE);
- if (interface_on_event(facemgr->hl, facelet) < 0) {
+ rc = interface_on_event(facemgr->hl, facelet);
+ if (rc < 0) {
ERROR("[facemgr_process_facelet] Failed to create face");
+ reason = -rc;
goto ERR;
}
@@ -1058,8 +1078,10 @@ facemgr_process_facelet(facemgr_t * facemgr, facelet_t * facelet)
case FACELET_STATUS_UPDATE:
facelet_set_event(facelet, FACELET_EVENT_UPDATE);
- if (interface_on_event(facemgr->hl, facelet) < 0) {
+ rc = interface_on_event(facemgr->hl, facelet);
+ if (rc < 0) {
ERROR("[facemgr_process_facelet] Failed to update face");
+ reason = -rc;
goto ERR;
}
@@ -1069,8 +1091,10 @@ facemgr_process_facelet(facemgr_t * facemgr, facelet_t * facelet)
case FACELET_STATUS_DELETE:
facelet_set_event(facelet, FACELET_EVENT_DELETE);
- if (interface_on_event(facemgr->hl, facelet) < 0) {
+ rc = interface_on_event(facemgr->hl, facelet);
+ if (rc < 0) {
ERROR("[facemgr_process_facelet] Failed to delete face");
+ reason = -rc;
goto ERR;
}
@@ -1080,6 +1104,8 @@ facemgr_process_facelet(facemgr_t * facemgr, facelet_t * facelet)
facelet_unset_local_port(facelet);
facelet_unset_remote_addr(facelet);
facelet_unset_remote_port(facelet);
+ facelet_unset_admin_state(facelet);
+ facelet_unset_state(facelet);
facelet_unset_bj_done(facelet);
#ifdef WITH_ANDROID_UTILITY
facelet_unset_au_done(facelet);
@@ -1100,11 +1126,11 @@ facemgr_process_facelet(facemgr_t * facemgr, facelet_t * facelet)
goto ERR;
}
- facelet_set_status_error(facelet, false);
+ facelet_unset_error(facelet);
return 0;
ERR:
- facelet_set_status_error(facelet, true);
+ facelet_set_error(facelet, reason);
return -1;
}
@@ -1120,11 +1146,12 @@ facemgr_reattempt_timeout(facemgr_t * facemgr, int fd, void * data)
int n = facelet_set_get_array(facemgr->facelet_cache, &facelet_array);
if (n < 0) {
ERROR("[facemgr_reattempt_timeout] Could not retrieve facelets in cache");
+ has_error = true;
} else {
for (unsigned i = 0; i < n; i++) {
facelet_t * facelet = facelet_array[i];
- if (!facelet_get_status_error(facelet))
+ if (!facelet_get_error(facelet))
continue;
char buf[MAXSZ_FACELET];
@@ -1135,7 +1162,7 @@ facemgr_reattempt_timeout(facemgr_t * facemgr, int fd, void * data)
has_error = true;
continue;
}
- facelet_set_status_error(facelet, false);
+ facelet_unset_error(facelet);
}
free(facelet_array);
}
@@ -1227,6 +1254,82 @@ facemgr_process_facelet_create(facemgr_t * facemgr, facelet_t * facelet)
return 0;
}
+/*
+ * \return 0 in case of success and no static facelet was added, 1 if a static
+ * facelet was added, and -1 in case of error.
+ */
+int
+facemgr_consider_static_facelet(facemgr_t * facemgr, facelet_t * facelet)
+{
+ /*
+ * We need to analyze the facelet and eventually:
+ * - add it in our static list
+ * - replicate it on multipath interfaces
+ */
+ netdevice_type_t netdevice_type;
+ if (facelet_get_netdevice_type(facelet, &netdevice_type) < 0)
+ return -1;
+
+ if ((netdevice_type == NETDEVICE_TYPE_UNDEFINED) ||
+ (netdevice_type == NETDEVICE_TYPE_LOOPBACK))
+ return 0;
+
+ if ((facelet_get_route_array(facelet, NULL) == 0))
+ return 0;
+
+ /*
+ * How to differenciate facelet created by face manager from user
+ * created ones ? This cannot be a flag in the facelet as it needs
+ * to work across restarts of the face manager...
+ * Also we might have two default routes.
+ *
+ * TODO:
+ * - The static one should not be a duplicate of the one we would
+ * create by default....
+ * - This should anyways be detected...
+ *
+ * One solution would be to install the default ones as static but
+ * this requires to implement a priority scheme between some of the
+ * static routes so that the override mechanism continues to work as
+ * usual.
+ *
+ * Current, we recognize the routes created by default by the face
+ * maanger thanks to the routing prefixes (a single default route).
+ */
+
+ facelet_t * static_facelet = facelet_dup(facelet);
+ facelet_unset_netdevice(static_facelet);
+ facelet_unset_netdevice_type(static_facelet);
+ facelet_unset_local_addr(static_facelet);
+ facelet_unset_local_port(static_facelet);
+
+ facelet_t * facelet_found = NULL;
+ if (facelet_array_get(facemgr->static_facelets, static_facelet, &facelet_found) < 0) {
+ ERROR("[facemgr_consider_static_facelet] Error checking whether static facelet already exists or not");
+ return -1;
+ }
+
+ /* Skip addition if facelet exists */
+ if (facelet_found)
+ return 0;
+
+ if (facelet_array_add(facemgr->static_facelets, static_facelet) < 0) {
+ ERROR("[facemgr_consider_static_facelet] Could not add facelet to static array");
+ facelet_free(static_facelet);
+ return -1;
+ }
+
+ char facelet_s[MAXSZ_FACELET];
+ int rc = facelet_snprintf(facelet_s, MAXSZ_FACELET, static_facelet);
+ if (rc >= MAXSZ_FACELET)
+ ERROR("[facemgr_consider_static_facelet] Unexpected truncation of facelet string");
+ if (rc < 0)
+ ERROR("[facemgr_consider_static_facelet] Error during facelet string output");
+ DEBUG("[facemgr_consider_static_facelet] Successfully added facelet to static array %s", facelet_s);
+
+ return 1;
+}
+
/**
* \brief Process facelet GET event
* \param [in] facemgr - Pointer to the face manager instance
@@ -1237,16 +1340,34 @@ facemgr_process_facelet_create(facemgr_t * facemgr, facelet_t * facelet)
int
facemgr_process_facelet_get(facemgr_t * facemgr, facelet_t * facelet)
{
- if (facelet_has_netdevice(facelet)) {
- netdevice_t netdevice;
- if (facelet_get_netdevice(facelet, &netdevice) < 0)
- return -1;
- if (!IS_VALID_NETDEVICE(netdevice))
- return -2;
- facelet_set_status(facelet, FACELET_STATUS_CLEAN);
- return facelet_set_add(facemgr->facelet_cache, facelet);
+ assert(facelet);
+
+ if (!facelet_has_netdevice(facelet))
+ return -2;
+
+ netdevice_t netdevice;
+ if (facelet_get_netdevice(facelet, &netdevice) < 0)
+ return -1;
+ if (!IS_VALID_NETDEVICE(netdevice))
+ return -2;
+ facelet_set_status(facelet, FACELET_STATUS_CLEAN);
+
+ int n = facemgr_consider_static_facelet(facemgr, facelet);
+ if (n < 0) {
+ ERROR("[facemgr_process_facelet_get] Could not add facelet to static array");
+ return -1;
+ }
+ if (n == 1) {
+ /*
+ * As a static facelet, it receives a new id not to be confused in the
+ * cache with default facelets
+ */
+ facelet_set_id(facelet, ++facemgr->cur_static_id);
}
- return -2;
+
+ char facelet_s[MAXSZ_FACELET];
+ facelet_snprintf(facelet_s, MAXSZ_FACELET, facelet);
+ return facelet_set_add(facemgr->facelet_cache, facelet);
}
/**
@@ -1341,6 +1462,9 @@ int facemgr_process_facelet_first_time(facemgr_t * facemgr, facelet_t * facelet)
{
facelet_set_status(facelet, FACELET_STATUS_UNCERTAIN);
+ assert(facelet);
+ char facelet_s[MAXSZ_FACELET];
+ facelet_snprintf(facelet_s, MAXSZ_FACELET, facelet);
if (facelet_set_add(facemgr->facelet_cache, facelet) < 0) {
ERROR("[facemgr_process_facelet_first_time] Error adding facelet to cache");
goto ERR_CACHE;
@@ -1372,15 +1496,28 @@ int
facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in)
{
bool remove_facelet = true;
+ bool dump = true;
int ret = 0;
int rc;
assert(facelet_in);
+ /* Update Netdevice type */
+ if (facelet_has_netdevice(facelet_in) && (!facelet_has_netdevice_type(facelet_in))) {
+ netdevice_t netdevice = NETDEVICE_EMPTY;
+
+ rc = facelet_get_netdevice(facelet_in, &netdevice);
+ if (rc < 0) {
+ ERROR("[facemgr_on_event] Error retrieving netdevice from facelet");
+ return -1;
+ }
+ facelet_set_netdevice_type(facelet_in, facemgr_get_netdevice_type(facemgr, netdevice.name));
+ }
+
char facelet_s[MAXSZ_FACELET];
facelet_snprintf(facelet_s, MAXSZ_FACELET, facelet_in);
- DEBUG("EVENT %s", facelet_s);
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");
@@ -1399,18 +1536,9 @@ facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in)
* Assumption: we should always see the link before the address
* assignment
*/
+ DEBUG("[facemgr_on_event] CREATE NEW %s", facelet_s);
assert(!facelet_has_family(facelet_in));
- if (!facelet_has_netdevice_type(facelet_in)) {
- netdevice_t netdevice = NETDEVICE_EMPTY;
- rc = facelet_get_netdevice(facelet_in, &netdevice);
- if (rc < 0) {
- ERROR("[facemgr_complement_facelet] Error retrieving netdevice from facelet");
- return -1;
- }
- facelet_set_netdevice_type(facelet_in, facemgr_get_netdevice_type(facemgr, netdevice.name));
- }
-
/* Create default v4 and v6 facelets */
facelet_t * facelet_v4 = facelet_dup(facelet_in);
if (!facelet_v4) {
@@ -1472,7 +1600,7 @@ facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in)
continue;
}
/* The id must be different than 0 */
- facelet_set_id(facelet_new, i+1);
+ facelet_set_id(facelet_new, ++facemgr->cur_static_id);
facelet_set_status(facelet_new, FACELET_STATUS_CLEAN);
char buf[MAXSZ_FACELET];
@@ -1493,9 +1621,11 @@ facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in)
case FACELET_EVENT_GET:
/* Insert new facelet in cached */
+ DEBUG("[facemgr_on_event] GET NEW %s", facelet_s);
rc = facemgr_process_facelet_get(facemgr, facelet_in);
if (rc == 0)
remove_facelet = false;
+ dump = false;
if (rc == -1) {
ERROR("[facemgr_on_event] Error processing GET event");
goto ERR;
@@ -1506,20 +1636,21 @@ facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in)
/* Might be because we previously ignored the facelet... */
//ERROR("[facemgr_on_event] Unexpected UPDATE... face does not exist");
//goto ERR;
+ DEBUG("[facemgr_on_event] UPDATE NEW %s", facelet_s);
INFO("Ignored UPDATE for non-existing face");
break;
case FACELET_EVENT_DELETE:
+ DEBUG("[facemgr_on_event] DELETE NEW %s", facelet_s);
ERROR("[facemgr_on_event] Unexpected DELETE... face does not exist");
goto ERR;
case FACELET_EVENT_UNDEFINED:
+ case FACELET_EVENT_N:
ERROR("[facemgr_on_event] Unexpected UNDEFINED event.");
+ ret = -1;
goto ERR;
- default: /* XXX Some events should be deprecated */
- ERROR("[facemgr_on_event] Deprecated event");
- goto ERR;
}
goto DUMP_CACHE;
}
@@ -1534,8 +1665,14 @@ facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in)
* reconciliation by sending appropriate updates to the forwarder
*/
facelet_t * facelet = cached_facelets[i];
+
+ char facelet_s[MAXSZ_FACELET];
+ facelet_snprintf(facelet_s, MAXSZ_FACELET, facelet);
+ //DEBUG("Facelet from cache #%d %s", i, facelet_s);
+
switch(facelet_get_event(facelet_in)) {
case FACELET_EVENT_CREATE:
+ DEBUG("[facemgr_on_event] CREATE EXISTING %s", facelet_s);
// 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
@@ -1552,13 +1689,17 @@ facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in)
continue;
case FACELET_EVENT_GET: /* should be an INFORM message */
- // FIXME, this might occur if the forwarder restarts and we
- // resync faces...
- ERROR("[facemgr_on_event] GET event for a face that already exists...");
- ret = -1;
+ /*
+ * This happens due to polling of the forwarder (or when it
+ * restarts)
+ */
+ DEBUG("[facemgr_on_event] GET EXISTING %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);
if (facelet_merge(facelet, facelet_in) < 0) {
ERROR("[facemgr_on_event] Error merging facelets");
continue;
@@ -1570,6 +1711,7 @@ facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in)
continue;
case FACELET_EVENT_DELETE:
+ DEBUG("[facemgr_on_event] DELETE EXISTING %s", facelet_s);
if (facelet_merge(facelet, facelet_in) < 0) {
ERROR("[facemgr_on_event] Error merging facelets");
continue;
@@ -1580,9 +1722,12 @@ facemgr_on_event(facemgr_t * facemgr, facelet_t * facelet_in)
}
continue;
- default: /* XXX Some events should be deprecated */
- ERROR("[facemgr_on_event] Deprecated event");
+ case FACELET_EVENT_UNDEFINED:
+ case FACELET_EVENT_N:
+ ERROR("[facemgr_on_event] Unexpected UNDEFINED event.");
ret = -1;
+ goto ERR;
+
}
}
@@ -1593,11 +1738,13 @@ ERR:
DUMP_CACHE:
#if 1
- DEBUG(" <CACHE>");
- facelet_set_dump(facemgr->facelet_cache);
- DEBUG(" </CACHE>");
- DEBUG("</EVENT ret=%d>", ret);
- DEBUG("----------------------------------");
+ if (dump) {
+ DEBUG(" <CACHE>");
+ facelet_set_dump(facemgr->facelet_cache);
+ DEBUG(" </CACHE>");
+ DEBUG("</EVENT ret=%d>", ret);
+ DEBUG("----------------------------------");
+ }
#endif
free(cached_facelets);
@@ -1684,41 +1831,54 @@ facemgr_bootstrap(facemgr_t * facemgr)
DEBUG("Registering interfaces...");
rc = interface_register(&hicn_light_ops);
if (rc < 0) {
- ERROR("Could not register interfaces");
+ ERROR("[facemgr_bootstrap] Error registering hicn_light interface");
goto ERR_REGISTER;
}
#ifdef __APPLE__
rc = interface_register(&network_framework_ops);
- if (rc < 0)
+ if (rc < 0) {
+ ERROR("[facemgr_bootstrap] Error registering network_framework interface");
goto ERR_REGISTER;
+ }
#endif /* __APPLE__ */
#ifdef __linux__
rc = interface_register(&netlink_ops);
- if (rc < 0)
+ if (rc < 0) {
+ ERROR("[facemgr_bootstrap] Error registering netlink interface");
goto ERR_REGISTER;
+ }
+
rc = interface_register(&bonjour_ops);
- if (rc < 0)
+ if (rc < 0) {
+ ERROR("[facemgr_bootstrap] Error registering bonjour interface");
goto ERR_REGISTER;
+ }
#endif /* __linux__ */
#ifdef WITH_ANDROID_UTILITY
rc = interface_register(&android_utility_ops);
- if (rc < 0)
+ if (rc < 0) {
+ ERROR("[facemgr_bootstrap] Error registering android_utility interface");
goto ERR_REGISTER;
+ }
#endif /* WITH_ANDROID_UTILITY */
#ifdef WITH_EXAMPLE_DUMMY
rc = interface_register(&dummy_ops);
- if (rc < 0)
+ if (rc < 0) {
+ ERROR("[facemgr_bootstrap] Error registering dummy interface");
goto ERR_REGISTER;
+ }
#endif
#ifdef WITH_EXAMPLE_UPDOWN
rc = interface_register(&updown_ops);
- if (rc < 0)
+ if (rc < 0) {
+ ERROR("[facemgr_bootstrap] Error registering updown interface");
goto ERR_REGISTER;
+ }
#endif
rc = facemgr_create_interface(facemgr, "hl", "hicn_light", NULL, &facemgr->hl);
@@ -1776,7 +1936,6 @@ facemgr_bootstrap(facemgr_t * facemgr)
return 0;
- /* FIXME facemgr_delete_interface */
#ifdef WITH_EXAMPLE_UPDOWN
facemgr_delete_interface(facemgr, facemgr->updown);
ERR_UPDOWN_CREATE:
diff --git a/ctrl/facemgr/src/facelet.c b/ctrl/facemgr/src/facelet.c
index 7a34b18c8..929005f57 100644
--- a/ctrl/facemgr/src/facelet.c
+++ b/ctrl/facemgr/src/facelet.c
@@ -47,15 +47,19 @@ const char * face_type_encap_str[] = {
#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
#undef _
};
-/* Facelet attribute status */
+const char * facelet_error_reason_str[] = {
+#define _(x) [FACELET_ERROR_REASON_ ## x] = STRINGIZE(x),
+ foreach_facelet_error_reason
+#undef _
+};
+/* Facelet attribute status */
const char * facelet_attr_status_str[] = {
#define _(x, str) [FACELET_ATTR_STATUS_ ## x] = STRINGIZE(x),
@@ -85,7 +89,7 @@ struct facelet_s {
facelet_status_t status;
- bool status_error;
+ int error;
facelet_event_t event;
@@ -120,10 +124,13 @@ facelet_create()
facelet->remote_port_status = FACELET_ATTR_STATUS_UNSET;
facelet->admin_state_status = FACELET_ATTR_STATUS_UNSET;
facelet->state_status = FACELET_ATTR_STATUS_UNSET;
+#ifdef WITH_POLICY
+ facelet->priority_status = FACELET_ATTR_STATUS_UNSET;
+#endif /* WITH_POLICY */
facelet->face_type_status = FACELET_ATTR_STATUS_UNSET;
facelet->status = FACELET_STATUS_UNDEFINED;
- facelet->status_error = false;
+ facelet->error = 0;
facelet->bj_done = false;
facelet->au_done = false;
@@ -229,7 +236,8 @@ facelet_create_from_face(face_t * face)
/* Attribute : netdevice */
/* NOTE index is not set */
if (IS_VALID_NETDEVICE(face->netdevice)) {
- facelet->netdevice = face->netdevice;
+ /* /!\ A face has only the netdevice name */
+ netdevice_set_name(&facelet->netdevice, face->netdevice.name);
facelet->netdevice_status = FACELET_ATTR_STATUS_CLEAN;
} else {
facelet->netdevice_status = FACELET_ATTR_STATUS_UNSET;
@@ -240,7 +248,7 @@ facelet_create_from_face(face_t * face)
if (facelet->netdevice_type != NETDEVICE_TYPE_UNDEFINED) {
facelet->netdevice_type_status = FACELET_ATTR_STATUS_CLEAN;
} else {
- facelet->netdevice = NETDEVICE_EMPTY;
+ facelet->netdevice_type = NETDEVICE_TYPE_UNDEFINED;
facelet->netdevice_type_status = FACELET_ATTR_STATUS_UNSET;
}
@@ -307,6 +315,16 @@ facelet_create_from_face(face_t * face)
facelet->state_status = FACELET_ATTR_STATUS_UNSET;
}
+#ifdef WITH_POLICY
+ /* Attribute : priority */
+ if (face->priority > 0) {
+ facelet->priority = face->priority;
+ facelet->priority_status = FACELET_ATTR_STATUS_CLEAN;
+ } else {
+ facelet->priority_status = FACELET_ATTR_STATUS_UNSET;
+ }
+#endif /* WITH_POLICY */
+
/* Attribute : face_type */
if ((face->type != FACE_TYPE_UNDEFINED) && (face->type != FACE_TYPE_N)) {
switch(face->type) {
@@ -330,7 +348,7 @@ facelet_create_from_face(face_t * face)
/* Status */
facelet->status = FACELET_STATUS_CLEAN;
- facelet->status_error = false;
+ facelet->error = 0;
/* TODO Consistency check between face type and found attributes */
if (facelet_validate_face(facelet) < 0)
@@ -407,13 +425,32 @@ facelet_dup(const facelet_t * current_facelet)
} else {
for (unsigned i = 0; i < n; i++) {
hicn_route_t * route = route_array[i];
- route_set_add(facelet->routes, route);
+ hicn_route_t * new_route = hicn_route_dup(route);
+ if (!new_route)
+ goto ERR_ROUTE;
+ route_set_add(facelet->routes, new_route);
}
}
free(route_array);
return facelet;
+ERR_ROUTE:
+ {
+ /* Free all routes */
+ hicn_route_t ** new_route_array;
+ int n = route_set_get_array(facelet->routes, &new_route_array);
+ if (n < 0) {
+ ERROR("[facelet_free] Error getting route set associated to facelet");
+ } else {
+ for (unsigned i = 0; i < n; i++) {
+ hicn_route_t * new_route = new_route_array[i];
+ hicn_route_free(new_route);
+ }
+ }
+ free(route_array);
+ facelet_free(facelet);
+ }
ERR_CREATE:
return NULL;
}
@@ -489,7 +526,6 @@ do {
} \
} while(0)
-/* facelet_match is the incoming one */
bool
facelet_equals(const facelet_t * facelet1, const facelet_t * facelet2)
{
@@ -786,6 +822,15 @@ facelet_get_face(const facelet_t * facelet, face_t ** pface)
face->state = FACE_STATE_UP;
}
+#ifdef WITH_POLICY
+ /* Priority */
+ if (facelet_has_priority(facelet)) {
+ if (facelet_get_priority(facelet, &face->priority) < 0)
+ goto ERR;
+ } else {
+ face->priority = 0;
+ }
+
/* Tags */
/* - based on netdevice type */
@@ -816,6 +861,7 @@ facelet_get_face(const facelet_t * facelet, face_t ** pface)
}
}
face->tags = tags;
+#endif /* WITH_POLICY */
*pface = face;
@@ -852,15 +898,35 @@ facelet_set_status(facelet_t * facelet, facelet_status_t status)
}
void
-facelet_set_status_error(facelet_t * facelet, bool value)
+facelet_set_error(facelet_t * facelet, facelet_error_reason_t reason)
{
- facelet->status_error = value;
+ facelet->error++;
+ switch(reason) {
+ case FACELET_ERROR_REASON_UNSPECIFIED_ERROR:
+ case FACELET_ERROR_REASON_INTERNAL_ERROR:
+ case FACELET_ERROR_REASON_PERMISSION_DENIED:
+ if (facelet->error >= FACELET_MAX_ERRORS)
+ facelet_set_status(facelet, FACELET_STATUS_IGNORED);
+ break;
+ case FACELET_ERROR_REASON_FORWARDER_OFFLINE:
+ break;
+ case FACELET_ERROR_REASON_UNDEFINED:
+ case FACELET_ERROR_REASON_N:
+ ERROR("facelet_set_error] Unexpected error reason");
+ break;
+ }
+}
+
+void
+facelet_unset_error(facelet_t * facelet)
+{
+ facelet->error = 0;
}
bool
-facelet_get_status_error(const facelet_t * facelet)
+facelet_get_error(const facelet_t * facelet)
{
- return facelet->status_error;
+ return facelet->error;
}
void
@@ -934,7 +1000,7 @@ facelet_snprintf(char * s, size_t size, const facelet_t * facelet)
/* Header + key attributes (netdevice + family) */
rc = snprintf(cur, s + size - cur, "<Facelet %s %s (%s)",
facelet_status_str[facelet->status],
- facelet_get_status_error(facelet) ? "/!\\" : "",
+ facelet_get_error(facelet) ? "/!\\" : "",
(facelet->family == AF_INET) ? "AF_INET" :
(facelet->family == AF_INET6) ? "AF_INET6" :
(facelet->family == AF_UNSPEC) ? "AF_UNSPEC" :
@@ -1062,6 +1128,18 @@ facelet_snprintf(char * s, size_t size, const facelet_t * facelet)
return cur - s;
}
+#ifdef WITH_POLICY
+ /* Priority */
+ if (facelet_has_priority(facelet)) {
+ rc = snprintf(cur, s + size - cur, " priority=%d", facelet->priority);
+ if (rc < 0)
+ return rc;
+ cur += rc;
+ if (cur >= s + size)
+ return cur - s;
+ }
+#endif /* WITH_POLICY */
+
/* Face type */
if (facelet_has_face_type(facelet)) {
rc = snprintf(cur, s + size - cur, " face_type=LAYER%s/%s",
@@ -1284,6 +1362,19 @@ int facelet_snprintf_json(char * s, size_t size, const facelet_t * facelet, int
return cur - s;
}
+#ifdef WITH_POLICY
+ /* Priority */
+ if (facelet_has_priority(facelet)) {
+ rc = snprintf(cur, s + size - cur, "%*s%s: %d,\n", 4 * (indent+1), "",
+ "\"priority\"", facelet->priority);
+ if (rc < 0)
+ return rc;
+ cur += rc;
+ if (cur >= s + size)
+ return cur - s;
+ }
+#endif /* WITH_POLICY */
+
if (facelet_has_face_type(facelet)) {
rc = snprintf(cur, s + size - cur, "%*s%s: \"LAYER%s/%s\",\n", 4 * (indent+1), "",
"\"face_type\"",
@@ -1298,7 +1389,7 @@ int facelet_snprintf_json(char * s, size_t size, const facelet_t * facelet, int
/* Status error */
rc = snprintf(cur, s + size - cur, "%*s%s: \"%s\"\n", 4 * (indent+1), "",
"\"error\"",
- facelet_get_status_error(facelet) ? "true" : "false");
+ facelet_get_error(facelet) ? "true" : "false");
if (rc < 0)
return rc;
cur += rc;
diff --git a/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c b/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c
index 945b60af2..a6cd44fe0 100644
--- a/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c
+++ b/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c
@@ -28,17 +28,23 @@
#include <hicn/util/log.h>
#include <hicn/util/map.h>
+#include "../../common.h"
#include "../../interface.h"
#define DEFAULT_ROUTE_COST 0
#define INTERVAL_MS 1000
+#define WITH_POLL
+
typedef enum {
HL_STATE_UNDEFINED,
- HL_STATE_CONNECTING,
+ HL_STATE_IDLE,
+ HL_STATE_ROUTES_SENT,
+ HL_STATE_ROUTES_RECEIVED,
HL_STATE_FACES_SENT,
- HL_STATE_DONE,
+ HL_STATE_FACES_RECEIVED,
+ HL_STATE_N
} hl_state_t;
typedef struct {
@@ -50,31 +56,63 @@ typedef struct {
/* Timer used to periodically poll the forwarder face and routing tables */
int poll_timer_fd;
+ hc_data_t * polled_routes;
} hl_data_t;
/* Forward declarations */
int hl_timeout(interface_t * interface, int fd, void * unused);
+#ifdef WITH_POLL
+int hl_process_state(interface_t * interface, int fd, void * unused)
+#else
int hl_process_state(interface_t * interface)
+#endif
{
hl_data_t * data = (hl_data_t *)interface->data;
+ /*
+ * Every tick we need to probe the forwarder for the list of faces and
+ * associated routes.
+ *
+ * This is used to guess manually added faces and routes
+ *
+ * TODO ensure we are idle at tick time
+ */
+
switch(data->state)
{
- case HL_STATE_UNDEFINED: // FIXME
- case HL_STATE_CONNECTING: // FIXME
- if (hc_face_list_async(data->s) < 0) {
- /* Blocking call */
- printf("Could not retrieve face list\n");
+ case HL_STATE_IDLE:
+ assert(!data->polled_routes);
+
+ //DEBUG("[hl_process_state] Querying route list");
+ if (hc_route_list_async(data->s) < 0) {
+ DEBUG("[hl_process_state] Error querying route list");
return -1;
}
+ data->state = HL_STATE_ROUTES_SENT;
break;
- case HL_STATE_FACES_SENT:
+
+ case HL_STATE_ROUTES_RECEIVED:
+ //DEBUG("[hl_process_state] Querying face list");
+ if (hc_face_list_async(data->s) < 0) {
+ DEBUG("[hl_process_state] Error querying face list");
+ return -1;
+ }
+ data->state = HL_STATE_FACES_SENT;
+ break;
break;
- default: /* HL_STATE_DONE never called */
+ case HL_STATE_FACES_RECEIVED:
+ data->state = HL_STATE_IDLE;
break;
+
+ case HL_STATE_ROUTES_SENT:
+ case HL_STATE_FACES_SENT:
+ case HL_STATE_UNDEFINED:
+ case HL_STATE_N:
+ ERROR("[hl_process_state] Unexpected state");
+ return -1;
}
return 0;
@@ -92,9 +130,21 @@ hl_after_connect(interface_t * interface)
goto ERR_FD;
}
- data->state = HL_STATE_UNDEFINED;
+ /* We always restart from the idle phase */
+ data->state = HL_STATE_IDLE;
+
+/* poll will replace the original get, ideally we would get notifications */
+#ifdef WITH_POLL
+ data->poll_timer_fd = interface_register_timer(interface, INTERVAL_MS,
+ hl_process_state, interface);
+ if (data->poll_timer_fd < 0) {
+ ERROR("[hc_connect] Could not initialize polling timer");
+ return -1;
+ }
+#else
hl_process_state(interface);
+#endif
return 0;
@@ -108,6 +158,10 @@ int _hl_connect(interface_t * interface);
int
hl_connect_timeout(interface_t * interface, int fd, void * unused)
{
+ hl_data_t * data = interface->data;
+ assert(fd == data->reconnect_timer_fd);
+ _unused(data);
+
int rc = _hl_connect(interface);
if (rc < 0) {
DEBUG("[hl_initialize] Error during connection reattempt; next attempt in %ds", INTERVAL_MS / 1000);
@@ -156,6 +210,12 @@ int hl_disconnect(interface_t * interface)
if (data->reconnect_timer_fd > 0)
interface_unregister_timer(interface, data->reconnect_timer_fd);
+ if (data->poll_timer_fd > 0)
+ interface_unregister_timer(interface, data->poll_timer_fd);
+
+ if (data->polled_routes)
+ hc_data_free(data->polled_routes);
+
if (data->s) {
interface_unregister_fd(interface, hc_sock_get_fd(data->s));
hc_sock_free(data->s);
@@ -194,6 +254,7 @@ hl_initialize(interface_t * interface, void * cfg)
data->s = NULL;
data->reconnect_timer_fd = 0;
+ data->poll_timer_fd = 0;
interface->data = data;
@@ -202,6 +263,8 @@ hl_initialize(interface_t * interface, void * cfg)
goto ERR_CONNECT;
}
+ data->polled_routes = NULL;
+
return 0;
ERR_CONNECT:
@@ -216,6 +279,9 @@ int hl_finalize(interface_t * interface)
hl_disconnect(interface);
+ if (data->polled_routes)
+ hc_data_free(data->polled_routes);
+
free(data);
return 0;
@@ -228,9 +294,12 @@ int hl_on_event(interface_t * interface, const facelet_t * facelet)
int rc;
int ret = 0;
hl_data_t * data = (hl_data_t *)interface->data;
-
face_t * face = NULL;
+ hc_face.id = 0;
+ memset(hc_face.name, 0, sizeof(hc_face.name));
+
+
/* NOTE
* - One example where this fails (and it is normal) is when we delete a
* face that was not completely created, because for instance bonjour did
@@ -238,11 +307,13 @@ int hl_on_event(interface_t * interface, const facelet_t * facelet)
*/
if (facelet_get_face(facelet, &face) < 0) {
ERROR("Could not retrieve face from facelet");
+ ret = -FACELET_ERROR_REASON_INTERNAL_ERROR;
goto ERR_FACE;
}
if (!data->s) {
/* We are not connected to the forwarder */
+ ret = -FACELET_ERROR_REASON_FORWARDER_OFFLINE;
goto ERR;
}
@@ -254,12 +325,13 @@ int hl_on_event(interface_t * interface, const facelet_t * facelet)
{
char buf[MAXSZ_FACELET];
facelet_snprintf(buf, MAXSZ_FACELET, facelet);
- printf("Create face %s\n", buf);
+ DEBUG("Create facelet %s", buf);
}
hc_face.face = *face;
rc = hc_face_create(data->s, &hc_face);
if (rc < 0) {
ERROR("Failed to create face\n");
+ ret = -FACELET_ERROR_REASON_UNSPECIFIED_ERROR;
goto ERR;
}
INFO("Created face id=%d", hc_face.id);
@@ -268,6 +340,7 @@ int hl_on_event(interface_t * interface, const facelet_t * facelet)
int n = facelet_get_route_array(facelet, &route_array);
if (n < 0) {
ERROR("Failed to create default hICN/IPv4 route");
+ ret = -FACELET_ERROR_REASON_UNSPECIFIED_ERROR;
goto ERR;
}
if (n == 0) {
@@ -326,7 +399,6 @@ int hl_on_event(interface_t * interface, const facelet_t * facelet)
continue;
}
}
-
}
break;
@@ -338,12 +410,13 @@ int hl_on_event(interface_t * interface, const facelet_t * facelet)
rc = hc_face_delete(data->s, &hc_face);
if (rc < 0) {
ERROR("Failed to delete face\n");
+ ret = -FACELET_ERROR_REASON_UNSPECIFIED_ERROR;
goto ERR;
}
break;
case FACELET_EVENT_UPDATE:
- /* Currently, only admin_state is supported */
+ /* Currently, only admin_state & priority are supported */
if (facelet_get_admin_state_status(facelet) == FACELET_ATTR_STATUS_DIRTY) {
hc_face.face = *face;
hc_face_t * face_found;
@@ -351,10 +424,12 @@ int hl_on_event(interface_t * interface, const facelet_t * facelet)
rc = hc_face_get(data->s, &hc_face, &face_found);
if (rc < 0) {
ERROR("Failed to find face\n");
+ ret = -FACELET_ERROR_REASON_INTERNAL_ERROR;
goto ERR;
}
if (!face_found) {
ERROR("Face to update has not been found");
+ ret = -FACELET_ERROR_REASON_UNSPECIFIED_ERROR;
goto ERR;
}
char conn_id_or_name[SYMBOLIC_NAME_LEN];
@@ -364,67 +439,188 @@ int hl_on_event(interface_t * interface, const facelet_t * facelet)
face_state_t admin_state;
if (facelet_get_admin_state(facelet, &admin_state) < 0) {
ERROR("Failed to retrieve facelet admin state");
+ ret = -FACELET_ERROR_REASON_INTERNAL_ERROR;
goto ERR;
}
if (hc_connection_set_admin_state(data->s, conn_id_or_name, admin_state) < 0) {
ERROR("Failed to update admin state");
+ ret = -FACELET_ERROR_REASON_UNSPECIFIED_ERROR;
goto ERR;
}
INFO("Admin state updated");
}
+ if (facelet_get_admin_state_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);
+
+ uint32_t priority;
+ if (facelet_get_priority(facelet, &priority) < 0) {
+ ERROR("Failed to retrieve facelet priority");
+ goto ERR;
+ }
+
+ if (hc_connection_set_priority(data->s, conn_id_or_name, priority) < 0) {
+ ERROR("Failed to update priority");
+ goto ERR;
+ }
+ INFO("Priority updated");
+ }
break;
default:
ERROR("Unknown event %s\n", facelet_event_str[facelet_get_event(facelet)]);
/* Unsupported events */
+ ret = -FACELET_ERROR_REASON_INTERNAL_ERROR;
goto ERR;
}
- face_free(face);
- return ret;
-
ERR:
face_free(face);
ERR_FACE:
- return -1;
+ return ret;
}
int hl_callback(interface_t * interface, int fd, void * unused)
{
hl_data_t * data = (hl_data_t*)interface->data;
+ hc_data_t * results;
+ int ret = 0;
- hc_data_t * faces;
- if (hc_sock_callback(data->s, &faces) < 0){
+ /* In case of error, reconnect to forwarder */
+ if (hc_sock_callback(data->s, &results) < 0) {
DEBUG("Closing socket... reconnecting...");
if (interface_unregister_fd(interface, hc_sock_get_fd(data->s)) < 0) {
- ERROR("[hl_initialize] Error registering fd");
+ ERROR("[hl_callback] Error unregistering fd");
}
+
+ /* Stopping poll timer */
+ if (interface_unregister_timer(interface, data->poll_timer_fd) < 0) {
+ ERROR("[hl_callback] Could not cancel polling timer after forwarder disconnect");
+ }
+ if (data->polled_routes)
+ hc_data_free(data->polled_routes);
+
hc_sock_free(data->s);
data->s = NULL;
hl_connect(interface);
- return 0;
+ return ret;
}
- if (faces->complete) {
- foreach_face(f, faces) {
+ /* Shall we wait for more data ? */
+ if (!results->complete)
+ return ret;
+
+ /* Process returned data */
+ switch(data->state) {
+
+ case HL_STATE_ROUTES_SENT:
+ //DEBUG("[hl_callback] Processing routes");
+ data->polled_routes = results;
+
#if 0
- char buf[MAXSZ_FACE];
- hc_face_snprintf(buf, MAXSZ_FACE, f);
- printf("Face: %s\n", buf);
+ foreach_route(r, results) {
+ char buf[MAXSZ_FACE];
+ int rc = hc_route_snprintf(route_s, MAXSZ_HC_ROUTE, r);
+ if (rc >= MAXSZ_HC_ROUTE)
+ ERROR("[hl_callback] Unexpected truncation of route string");
+ if (rc < 0)
+ ERROR("[hl_callback] Error during route string formatting");
+ DEBUG("Route: %s", buf);
+ }
#endif
- facelet_t * facelet = facelet_create_from_face(&f->face);
- facelet_set_event(facelet, FACELET_EVENT_GET);
- interface_raise_event(interface, facelet);
- }
- }
- hc_data_free(faces);
+ data->state = HL_STATE_ROUTES_RECEIVED;
+ if (hl_process_state(interface, fd, unused) < 0) {
+ ERROR("[hl_callback] Error processing state after routes received");
+ ret = -1;
+ }
+ break;
+
- /* XXX how do we know what object we get back */
+ case HL_STATE_FACES_SENT:
+ //DEBUG("[hl_callback] Processing faces");
+ assert(data->polled_routes);
+ foreach_face(f, results) {
+
+#if 0
+ char buf[MAXSZ_FACE];
+ int rc = hc_face_snprintf(buf, MAXSZ_FACE, f);
+ if (rc >= MAXSZ_HC_FACE)
+ ERROR("[hl_callback] Unexpected truncation of face string");
+ if (rc < 0)
+ ERROR("[hl_callback] Error during face string formatting");
+
+ DEBUG("Face: %s", buf);
+#endif
- /* We have a queue of pending data elements per active query */
+ /* We can ignore faces on localhost */
- return 0;
+ 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;
+
+#if 0
+ char route_s[MAXSZ_HC_ROUTE];
+ int rc = hc_route_snprintf(route_s, MAXSZ_HC_ROUTE, r);
+ if (rc >= MAXSZ_HC_ROUTE)
+ ERROR("[hl_callback] Unexpected truncation of route string");
+ if (rc < 0)
+ ERROR("[hl_callback] Error during route string formatting");
+ DEBUG("Associated route: %s", route_s);
+#endif
+
+ if (r->len == 0)
+ continue;
+
+ ip_prefix_t prefix = {
+ .family = r->family,
+ .address = r->remote_addr,
+ .len = r->len,
+ };
+ hicn_route_t * route = hicn_route_create(&prefix, r->face_id, r->cost);
+ facelet_add_route(facelet, route);
+ }
+
+ facelet_snprintf(facelet_s, MAXSZ_FACELET, facelet);
+ facelet_set_event(facelet, FACELET_EVENT_GET);
+ interface_raise_event(interface, facelet);
+ }
+
+ hc_data_free(data->polled_routes);
+ data->polled_routes = NULL;
+ data->state = HL_STATE_FACES_RECEIVED;
+ if (hl_process_state(interface, fd, unused) < 0) {
+ ERROR("[hl_callback] Error processing state after faces received");
+ ret = -1;
+ }
+ break;
+
+ case HL_STATE_IDLE:
+ case HL_STATE_FACES_RECEIVED:
+ case HL_STATE_ROUTES_RECEIVED:
+ case HL_STATE_UNDEFINED:
+ case HL_STATE_N:
+ ERROR("[hl_callback] Unexpected state");
+ ret = -1;
+ }
+
+ return ret;
}
const interface_ops_t hicn_light_ops = {
diff --git a/ctrl/libhicnctrl/examples/create_face.c b/ctrl/libhicnctrl/examples/create_face.c
index dcacaeff1..5f92f5906 100644
--- a/ctrl/libhicnctrl/examples/create_face.c
+++ b/ctrl/libhicnctrl/examples/create_face.c
@@ -107,7 +107,10 @@ int main() {
.remote_port = 6000,
.admin_state = FACE_STATE_UNDEFINED,
.state = FACE_STATE_UNDEFINED,
+#ifdef WITH_POLICY
+ .priority = 0,
.tags = POLICY_TAGS_EMPTY,
+#endif /* WITH_POLICY */
},
};
if (netdevice_set_name(&face.face.netdevice, if_name) < 0) {
diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/api.h b/ctrl/libhicnctrl/includes/hicn/ctrl/api.h
index b3032d0f3..c9c2f0da8 100644
--- a/ctrl/libhicnctrl/includes/hicn/ctrl/api.h
+++ b/ctrl/libhicnctrl/includes/hicn/ctrl/api.h
@@ -498,6 +498,7 @@ typedef struct {
u16 remote_port; /* .rw */
hc_connection_state_t admin_state; /* .rw */
#ifdef WITH_POLICY
+ uint32_t priority; /* .rw */
policy_tags_t tags; /* .rw */
#endif /* WITH_POLICY */
hc_connection_state_t state; /* .r. */
@@ -523,8 +524,9 @@ int hc_connection_validate(const hc_connection_t * connection);
int hc_connection_cmp(const hc_connection_t * c1, const hc_connection_t * c2);
int hc_connection_parse(void * in, hc_connection_t * connection);
-#ifdef WITH_POLICY
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);
#endif /* WITH_POLICY */
#define foreach_connection(VAR, data) foreach_type(hc_connection_t, VAR, data)
@@ -599,6 +601,7 @@ int hc_route_parse(void * in, hc_route_t * route);
int hc_route_create(hc_sock_t * s, hc_route_t * route);
int hc_route_delete(hc_sock_t * s, hc_route_t * route);
int hc_route_list(hc_sock_t * s, hc_data_t ** pdata);
+int hc_route_list_async(hc_sock_t * s);
#define foreach_route(VAR, data) foreach_type(hc_route_t, VAR, data)
diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/commands.h b/ctrl/libhicnctrl/includes/hicn/ctrl/commands.h
index a5bc15e8a..520559ccf 100644
--- a/ctrl/libhicnctrl/includes/hicn/ctrl/commands.h
+++ b/ctrl/libhicnctrl/includes/hicn/ctrl/commands.h
@@ -75,6 +75,7 @@ typedef enum {
LIST_POLICIES,
REMOVE_POLICY,
UPDATE_CONNECTION,
+ CONNECTION_SET_PRIORITY,
#endif /* WITH_POLICY */
LAST_COMMAND_VALUE
} command_id;
@@ -138,6 +139,7 @@ typedef struct {
uint8_t connectionType;
uint8_t admin_state;
#ifdef WITH_POLICY
+ uint32_t priority;
policy_tags_t tags;
#endif /* WITH_POLICY */
} add_connection_command;
@@ -166,6 +168,9 @@ typedef struct {
uint32_t connid;
uint8_t state;
uint8_t admin_state;
+#ifdef WITH_POLICY
+ uint32_t priority;
+#endif /* WITH_POLICY */
char interfaceName[SYMBOLIC_NAME_LEN];
char connectionName[SYMBOLIC_NAME_LEN];
} list_connections_command;
@@ -335,9 +340,15 @@ typedef struct {
typedef struct {
char symbolicOrConnid[SYMBOLIC_NAME_LEN];
uint8_t admin_state;
+ uint32_t priority;
policy_tags_t tags;
} update_connection_command;
+typedef struct {
+ char symbolicOrConnid[SYMBOLIC_NAME_LEN];
+ uint32_t priority;
+} connection_set_priority_command;
+
#endif /* WITH_POLICY */
//===== size of commands ======
@@ -394,6 +405,8 @@ static inline int payloadLengthDaemon(command_id id) {
return sizeof(remove_policy_command);
case UPDATE_CONNECTION:
return sizeof(update_connection_command);
+ case CONNECTION_SET_PRIORITY:
+ return sizeof(connection_set_priority_command);
#endif /* WITH_POLICY */
case LAST_COMMAND_VALUE:
return 0;
diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/face.h b/ctrl/libhicnctrl/includes/hicn/ctrl/face.h
index 5c1fecd55..f0a8045de 100644
--- a/ctrl/libhicnctrl/includes/hicn/ctrl/face.h
+++ b/ctrl/libhicnctrl/includes/hicn/ctrl/face.h
@@ -153,6 +153,7 @@ typedef struct {
face_state_t admin_state;
face_state_t state;
#ifdef WITH_POLICY
+ uint32_t priority;
policy_tags_t tags; /**< \see policy_tag_t */
#endif /* WITH_POLICY */
diff --git a/ctrl/libhicnctrl/includes/hicn/ctrl/route.h b/ctrl/libhicnctrl/includes/hicn/ctrl/route.h
index f67cccf93..2b96d22cc 100644
--- a/ctrl/libhicnctrl/includes/hicn/ctrl/route.h
+++ b/ctrl/libhicnctrl/includes/hicn/ctrl/route.h
@@ -31,6 +31,7 @@ typedef struct hicn_route_s hicn_route_t;
#define MAXSZ_ROUTE MAXSZ_ROUTE_ + NULLTERM
hicn_route_t * hicn_route_create(ip_prefix_t * prefix, face_id_t face_id, route_cost_t cost);
+hicn_route_t * hicn_route_dup(const hicn_route_t * route);
void hicn_route_free(hicn_route_t * route);
int hicn_route_cmp(const hicn_route_t * route1, const hicn_route_t * route2);
diff --git a/ctrl/libhicnctrl/src/api.c b/ctrl/libhicnctrl/src/api.c
index 6c9b54a92..14ee69b53 100644
--- a/ctrl/libhicnctrl/src/api.c
+++ b/ctrl/libhicnctrl/src/api.c
@@ -715,7 +715,6 @@ hc_sock_process(hc_sock_t * s, hc_data_t ** data)
available -= num_chunks * s->cur_request->data->in_element_size;
s->roff += num_chunks * s->cur_request->data->in_element_size;
if (s->remaining == 0) {
- printf("done, sock map remove\n");
if (hc_sock_map_remove(s->map, s->cur_request->seq, NULL) < 0) {
ERROR("[hc_sock_process] Error removing request from map");
return -1;
@@ -856,7 +855,6 @@ hc_execute_command(hc_sock_t * s, hc_msg_t * msg, size_t msg_len,
ERROR("[hc_execute_command] Could not get next sequence number");
goto ERR_SEQ;
}
- printf("Sending message with seq %d\n", seq);
/* Create state used to process the request */
hc_sock_request_t * request = NULL;
@@ -867,7 +865,6 @@ hc_execute_command(hc_sock_t * s, hc_msg_t * msg, size_t msg_len,
}
/* Add state to map */
- printf("sock map add\n");
if (hc_sock_map_add(s->map, seq, request) < 0) {
ERROR("[hc_execute_command] Error adding request state to map");
goto ERR_MAP;
@@ -1272,6 +1269,7 @@ _hc_connection_create(hc_sock_t * s, hc_connection_t * connection, bool async)
.connectionType = (u8)map_to_connection_type[connection->type],
.admin_state = connection->admin_state,
#ifdef WITH_POLICY
+ .priority = connection->priority,
.tags = connection->tags,
#endif /* WITH_POLICY */
}
@@ -1549,6 +1547,7 @@ hc_connection_parse(void * in, hc_connection_t * connection)
.remote_port = ntohs(cmd->connectionData.remotePort),
.admin_state = cmd->connectionData.admin_state,
#ifdef WITH_POLICY
+ .priority = cmd->connectionData.priority,
.tags = cmd->connectionData.tags,
#endif /* WITH_POLICY */
.state = state,
@@ -1649,6 +1648,56 @@ hc_connection_set_admin_state_async(hc_sock_t * s, const char * conn_id_or_name,
return _hc_connection_set_admin_state(s, conn_id_or_name, state, true);
}
+int
+_hc_connection_set_priority(hc_sock_t * s, const char * conn_id_or_name,
+ uint32_t priority, bool async)
+{
+ int rc;
+ DEBUG("[hc_connection_set_priority] connection_id/name=%s priority=%d async=%s",
+ conn_id_or_name, priority, BOOLSTR(async));
+ struct {
+ header_control_message hdr;
+ connection_set_priority_command payload;
+ } msg = {
+ .hdr = {
+ .messageType = REQUEST_LIGHT,
+ .commandID = CONNECTION_SET_ADMIN_STATE,
+ .length = 1,
+ .seqNum = 0,
+ },
+ .payload = {
+ .priority = priority,
+ },
+ };
+ rc = snprintf(msg.payload.symbolicOrConnid, SYMBOLIC_NAME_LEN, "%s", conn_id_or_name);
+ if (rc >= SYMBOLIC_NAME_LEN)
+ WARN("[_hc_connection_set_priority] Unexpected truncation of symbolic name string");
+
+ hc_command_params_t params = {
+ .cmd = ACTION_SET,
+ .cmd_id = CONNECTION_SET_PRIORITY,
+ .size_in = sizeof(connection_set_priority_command),
+ .size_out = 0,
+ .parse = NULL,
+ };
+
+ return hc_execute_command(s, (hc_msg_t*)&msg, sizeof(msg), &params, NULL, async);
+}
+
+int
+hc_connection_set_priority(hc_sock_t * s, const char * conn_id_or_name,
+ uint32_t priority)
+{
+ return _hc_connection_set_priority(s, conn_id_or_name, priority, false);
+}
+
+int
+hc_connection_set_priority_async(hc_sock_t * s, const char * conn_id_or_name,
+ uint32_t priority)
+{
+ return _hc_connection_set_priority(s, conn_id_or_name, priority, true);
+}
+
/*----------------------------------------------------------------------------*
* Routes
*----------------------------------------------------------------------------*/
@@ -1815,9 +1864,9 @@ hc_route_list(hc_sock_t * s, hc_data_t ** pdata)
}
int
-hc_route_list_async(hc_sock_t * s, hc_data_t ** pdata)
+hc_route_list_async(hc_sock_t * s)
{
- return _hc_route_list(s, pdata, true);
+ return _hc_route_list(s, NULL, true);
}
/* ROUTE PARSE */
@@ -1927,6 +1976,7 @@ hc_face_to_connection(const hc_face_t * face, hc_connection_t * connection, bool
.admin_state = face_state_to_connection_state(f->admin_state),
.state = face_state_to_connection_state(f->state),
#ifdef WITH_POLICY
+ .priority = f->priority,
.tags = f->tags,
#endif /* WITH_POLICY */
};
@@ -1946,6 +1996,7 @@ hc_face_to_connection(const hc_face_t * face, hc_connection_t * connection, bool
.admin_state = face_state_to_connection_state(f->admin_state),
.state = face_state_to_connection_state(f->state),
#ifdef WITH_POLICY
+ .priority = f->priority,
.tags = f->tags,
#endif /* WITH_POLICY */
};
@@ -1968,6 +2019,7 @@ hc_face_to_connection(const hc_face_t * face, hc_connection_t * connection, bool
.admin_state = face_state_to_connection_state(f->admin_state),
.state = face_state_to_connection_state(f->state),
#ifdef WITH_POLICY
+ .priority = f->priority,
.tags = f->tags,
#endif /* WITH_POLICY */
};
@@ -1978,6 +2030,8 @@ hc_face_to_connection(const hc_face_t * face, hc_connection_t * connection, bool
} else {
memset(connection->name, 0, SYMBOLIC_NAME_LEN);
}
+ snprintf(connection->interface_name, INTERFACE_LEN, "%s",
+ f->netdevice.name);
break;
default:
return -1;
@@ -2011,6 +2065,7 @@ hc_connection_to_face(const hc_connection_t * connection, hc_face_t * face)
.admin_state = connection_state_to_face_state(connection->admin_state),
.state = connection_state_to_face_state(connection->state),
#ifdef WITH_POLICY
+ .priority = connection->priority,
.tags = connection->tags,
#endif /* WITH_POLICY */
},
@@ -2029,6 +2084,7 @@ hc_connection_to_face(const hc_connection_t * connection, hc_face_t * face)
.admin_state = connection_state_to_face_state(connection->admin_state),
.state = connection_state_to_face_state(connection->state),
#ifdef WITH_POLICY
+ .priority = connection->priority,
.tags = connection->tags,
#endif /* WITH_POLICY */
},
@@ -2046,6 +2102,7 @@ hc_connection_to_face(const hc_connection_t * connection, hc_face_t * face)
.admin_state = connection_state_to_face_state(connection->admin_state),
.state = connection_state_to_face_state(connection->state),
#ifdef WITH_POLICY
+ .priority = connection->priority,
.tags = connection->tags,
#endif /* WITH_POLICY */
},
@@ -2366,7 +2423,7 @@ hc_connection_parse_to_face(void * in, hc_face_t * face)
int
-hc_face_list_async(hc_sock_t * s) //, hc_data_t ** pdata)
+hc_face_list_async(hc_sock_t * s)
{
struct {
header_control_message hdr;
@@ -2451,19 +2508,22 @@ hc_face_snprintf(char * s, size_t size, hc_face_t * face)
if (rc < 0)
return rc;
- return snprintf(s, size, "[#%d %s] %s %s %s %s/%s (%s)",
+ return snprintf(s, size, "[#%d %s] %s %s %s %s %s/%s [%d] (%s)",
face->id,
face->name,
+ face->face.netdevice.index != NETDEVICE_UNDEFINED_INDEX ? face->face.netdevice.name : "*",
face_type_str[face->face.type],
local,
remote,
face_state_str[face->face.state],
face_state_str[face->face.admin_state],
+ face->face.priority,
tags);
#else
- return snprintf(s, size, "[#%d %s] %s %s %s %s/%s",
+ return snprintf(s, size, "[#%d %s] %s %s %s %s %s/%s",
face->id,
face->name,
+ face->face.netdevice.index != NETDEVICE_UNDEFINED_INDEX ? face->face.netdevice.name : "*",
face_type_str[face->face.type],
local,
remote,
@@ -2473,12 +2533,19 @@ hc_face_snprintf(char * s, size_t size, hc_face_t * face)
}
int
-hc_face_set_admin_state(hc_sock_t * s, const char * conn_id_or_name, // XXX wrong identifier
+hc_face_set_admin_state(hc_sock_t * s, const char * conn_id_or_name,
face_state_t admin_state)
{
return hc_connection_set_admin_state(s, conn_id_or_name, admin_state);
}
+int
+hc_face_set_priority(hc_sock_t * s, const char * conn_id_or_name,
+ uint32_t priority)
+{
+ return hc_connection_set_priority(s, conn_id_or_name, priority);
+}
+
/*----------------------------------------------------------------------------*
* Punting
*----------------------------------------------------------------------------*/
diff --git a/ctrl/libhicnctrl/src/cli.c b/ctrl/libhicnctrl/src/cli.c
index a171f7045..879454c3a 100644
--- a/ctrl/libhicnctrl/src/cli.c
+++ b/ctrl/libhicnctrl/src/cli.c
@@ -379,7 +379,7 @@ parse_options(int argc, char *argv[], hc_command_t * command)
case OBJECT_FACE:
switch(command->action) {
case ACTION_CREATE:
- if ((argc - optind != 6) && (argc - optind != 7)) {
+ if ((argc - optind != 5) && (argc - optind != 6)) {
usage_face_create(argv[0], true, false);
goto ERR_PARAM;
}
diff --git a/ctrl/libhicnctrl/src/face.c b/ctrl/libhicnctrl/src/face.c
index 41ff58f81..0e25890da 100644
--- a/ctrl/libhicnctrl/src/face.c
+++ b/ctrl/libhicnctrl/src/face.c
@@ -129,6 +129,7 @@ netdevice_get_name(const netdevice_t * netdevice, const char ** name)
int
netdevice_set_name(netdevice_t * netdevice, const char * name)
{
+ memset(netdevice->name, 0, sizeof(netdevice->name));
int rc = snprintf(netdevice->name, IFNAMSIZ, "%s", name);
if (rc < 0)
return -1;
diff --git a/ctrl/libhicnctrl/src/route.c b/ctrl/libhicnctrl/src/route.c
index 61434871b..703b4763f 100644
--- a/ctrl/libhicnctrl/src/route.c
+++ b/ctrl/libhicnctrl/src/route.c
@@ -43,6 +43,16 @@ hicn_route_create(ip_prefix_t * prefix, face_id_t face_id, route_cost_t cost)
return route;
}
+hicn_route_t *
+hicn_route_dup(const hicn_route_t * route)
+{
+ hicn_route_t * new_route = malloc(sizeof(hicn_route_t));
+ if (!route)
+ return NULL;
+ memcpy(new_route, route, sizeof(hicn_route_t));
+ return new_route;
+}
+
void hicn_route_free(hicn_route_t * route)
{
free(route);
diff --git a/ctrl/sysrepo-plugins/hicn-plugin/plugin/model/hicn_model.c b/ctrl/sysrepo-plugins/hicn-plugin/plugin/model/hicn_model.c
index 4bf266ff5..bb8c5e828 100644
--- a/ctrl/sysrepo-plugins/hicn-plugin/plugin/model/hicn_model.c
+++ b/ctrl/sysrepo-plugins/hicn-plugin/plugin/model/hicn_model.c
@@ -1053,16 +1053,16 @@ static int hicn_face_ip_add_cb(const char *xpath, const sr_val_t *input,
struct sockaddr_in sa;
inet_pton(AF_INET, input[0].data.string_val, &(sa.sin_addr));
unsigned char * tmp = (unsigned char *) &sa.sin_addr.s_addr;
- memcpy(&msg->payload.local_addr.un.ip4[0],tmp,B32);
- msg->payload.local_addr.af = ADDRESS_IP4;
+ memcpy(&msg->payload.face.local_addr.un.ip4[0],tmp,B32);
+ msg->payload.face.local_addr.af = ADDRESS_IP4;
}else if(strcmp(input[1].data.string_val,"-1")){
void *dst = malloc(sizeof(struct in6_addr));
inet_pton(AF_INET6, input[1].data.string_val, dst);
unsigned char * tmp = (unsigned char *) ((struct in6_addr *)dst)->s6_addr;
- memcpy(&msg->payload.local_addr.un.ip6[0],tmp,B128);
- msg->payload.local_addr.af = ADDRESS_IP6;
+ memcpy(&msg->payload.face.local_addr.un.ip6[0],tmp,B128);
+ msg->payload.face.local_addr.af = ADDRESS_IP6;
}else{
SRP_LOG_DBG_MSG("Invalid local IP address");
@@ -1074,8 +1074,8 @@ static int hicn_face_ip_add_cb(const char *xpath, const sr_val_t *input,
struct sockaddr_in sa;
inet_pton(AF_INET, input[2].data.string_val, &(sa.sin_addr));
unsigned char * tmp = (unsigned char *)&sa.sin_addr.s_addr;
- memcpy(&msg->payload.remote_addr.un.ip4[0],tmp,B32);
- msg->payload.remote_addr.af = ADDRESS_IP4;
+ memcpy(&msg->payload.face.remote_addr.un.ip4[0],tmp,B32);
+ msg->payload.face.remote_addr.af = ADDRESS_IP4;
}else if(strcmp(input[3].data.string_val,"-1")){
@@ -1083,8 +1083,8 @@ static int hicn_face_ip_add_cb(const char *xpath, const sr_val_t *input,
void *dst = malloc(sizeof(struct in6_addr));
inet_pton(AF_INET6, input[3].data.string_val, dst);
unsigned char * tmp =(unsigned char *) ((struct in6_addr *)dst)->s6_addr;
- memcpy(&msg->payload.remote_addr.un.ip6[0],tmp,B128);
- msg->payload.remote_addr.af = ADDRESS_IP6;
+ memcpy(&msg->payload.face.remote_addr.un.ip6[0],tmp,B128);
+ msg->payload.face.remote_addr.af = ADDRESS_IP6;
}else{
SRP_LOG_DBG_MSG("Invalid local IP address");
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 ab0e0e6d8..1f5d33e24 100644
--- a/hicn-light/src/hicn/command_line/controller/hicnLightControl_main.c
+++ b/hicn-light/src/hicn/command_line/controller/hicnLightControl_main.c
@@ -82,6 +82,7 @@ static int payloadLengthController[LAST_COMMAND_VALUE] = {
sizeof(list_policies_command),
sizeof(remove_policy_command),
sizeof(update_connection_command),
+ sizeof(connection_set_priority_command),
#endif
};
diff --git a/hicn-light/src/hicn/config/configuration.c b/hicn-light/src/hicn/config/configuration.c
index 01192569f..f135dcc5a 100644
--- a/hicn-light/src/hicn/config/configuration.c
+++ b/hicn-light/src/hicn/config/configuration.c
@@ -420,6 +420,7 @@ struct iovec *configuration_ProcessCreateTunnel(Configuration *config,
Connection *conn = connection_Create(ops);
#ifdef WITH_POLICY
connection_SetTags(conn, control->tags);
+ connection_SetPriority(conn, control->priority);
#endif /* WITH_POLICY */
connection_SetAdminState(conn, control->admin_state);
@@ -443,6 +444,7 @@ struct iovec *configuration_ProcessCreateTunnel(Configuration *config,
} else {
#ifdef WITH_POLICY
connection_SetTags(conn, control->tags);
+ connection_SetPriority(conn, control->priority);
connection_SetAdminState(conn, control->admin_state);
#ifdef WITH_MAPME
@@ -704,6 +706,7 @@ struct iovec *configuration_ProcessConnectionList(Configuration *config,
listConnectionsCommand->connectionData.admin_state = connection_GetAdminState(original);
#ifdef WITH_POLICY
+ listConnectionsCommand->priority = connection_GetPriority(original);
listConnectionsCommand->connectionData.tags = connection_GetTags(original);
#endif /* WITH_POLICY */
@@ -1162,7 +1165,7 @@ struct iovec *configuration_ConnectionSetAdminState(Configuration *config,
connection_SetAdminState(conn, control->admin_state);
#ifdef WITH_MAPME
- /* Hook: new connection created through the control protocol */
+ /* Hook: connection event */
forwarder_onConnectionEvent(config->forwarder, conn,
control->admin_state == CONNECTION_STATE_UP
? CONNECTION_EVENT_SET_UP
@@ -1173,6 +1176,27 @@ struct iovec *configuration_ConnectionSetAdminState(Configuration *config,
}
#ifdef WITH_POLICY
+
+struct iovec *configuration_ConnectionSetPriority(Configuration *config,
+ struct iovec *request) {
+ header_control_message *header = request[0].iov_base;
+ connection_set_priority_command *control = request[1].iov_base;
+
+ Connection * conn = getConnectionBySymbolicOrId(config, control->symbolicOrConnid);
+ if (!conn)
+ return utils_CreateNack(header, control, sizeof(connection_set_priority_command));
+
+ connection_SetPriority(conn, control->priority);
+
+#ifdef WITH_MAPME
+ /* Hook: connection event */
+ forwarder_onConnectionEvent(config->forwarder, conn,
+ CONNECTION_EVENT_PRIORITY_CHANGED);
+#endif /* WITH_MAPME */
+
+ return utils_CreateAck(header, control, sizeof(connection_set_priority_command));
+}
+
struct iovec *configuration_ProcessPolicyAdd(Configuration *config,
struct iovec *request) {
header_control_message *header = request[0].iov_base;
@@ -1256,12 +1280,14 @@ struct iovec *configuration_UpdateConnection(Configuration *config,
Connection * conn = getConnectionBySymbolicOrId(config, control->symbolicOrConnid);
if (!conn)
- return utils_CreateNack(header, control, sizeof(connection_set_admin_state_command));
+ return utils_CreateNack(header, control, sizeof(update_connection_command));
connection_SetTags(conn, control->tags);
connection_SetAdminState(conn, control->admin_state);
+ if (control->priority > 0)
+ connection_SetPriority(conn, control->priority);
- return utils_CreateAck(header, control, sizeof(remove_policy_command));
+ return utils_CreateAck(header, control, sizeof(update_connection_command));
}
#endif /* WITH_POLICY */
@@ -1372,6 +1398,10 @@ struct iovec *configuration_DispatchCommand(Configuration *config,
case UPDATE_CONNECTION:
response = configuration_UpdateConnection(config, control);
break;
+
+ case CONNECTION_SET_PRIORITY:
+ response = configuration_ConnectionSetPriority(config, control);
+ break;
#endif /* WITH_POLICY */
default:
diff --git a/hicn-light/src/hicn/config/controlListConnections.c b/hicn-light/src/hicn/config/controlListConnections.c
index 0e8e2c30b..0613ac4f9 100644
--- a/hicn-light/src/hicn/config/controlListConnections.c
+++ b/hicn-light/src/hicn/config/controlListConnections.c
@@ -114,7 +114,7 @@ static CommandReturn _controlListConnections_Execute(CommandParser *parser,
}
#ifdef WITH_POLICY
- printf("%5s %10s %12s %6s %40s %40s %5s %s\n", "id", "name", "admin_state", "state", "source", "destination", "type", "flags");
+ printf("%5s %10s %12s %6s %40s %40s %5s %s %s\n", "id", "name", "admin_state", "state", "source", "destination", "type", "priority", "flags");
#else
printf("%5s %10s %12s %6s %40s %40s %5s\n", "id", "name", "admin_state", "state", "source", "destination", "type");
#endif /* WITH_POLICY */
@@ -147,11 +147,12 @@ foreach_policy_tag
*s = '\0';
parcBufferComposer_Format(
- composer, "%5d %10s %12s %6s %40s %40s %5s [%s]", listConnectionsCommand->connid, listConnectionsCommand->connectionName,
+ composer, "%5d %10s %12s %6s %40s %40s %5s [%d] [%s]", listConnectionsCommand->connid, listConnectionsCommand->connectionName,
stateString[listConnectionsCommand->admin_state],
stateString[listConnectionsCommand->state], sourceString,
destinationString,
connTypeString[listConnectionsCommand->connectionData.connectionType],
+ listConnectionsCommand->connectionData.priority,
flags_str);
#else
diff --git a/hicn-light/src/hicn/core/connection.c b/hicn-light/src/hicn/core/connection.c
index 6295d08df..8ec38f75f 100644
--- a/hicn-light/src/hicn/core/connection.c
+++ b/hicn-light/src/hicn/core/connection.c
@@ -332,6 +332,26 @@ void connection_SetAdminState(Connection *conn, connection_state_t admin_state)
ioOperations_SetAdminState(conn->ops, admin_state);
}
+#ifdef WITH_POLICY
+uint32_t connection_GetPriority(const Connection *conn)
+{
+ parcAssertNotNull(conn, "Parameter conn must be non-null");
+ if (!conn->ops)
+ return CONNECTION_STATE_UNDEFINED;
+ return ioOperations_GetPriority(conn->ops);
+}
+
+void connection_SetPriority(Connection *conn, uint32_t priority)
+{
+ parcAssertNotNull(conn, "Parameter conn must be non-null");
+ if (!conn->ops)
+ return;
+ if ((priority != CONNECTION_STATE_UP) && (priority != CONNECTION_STATE_DOWN))
+ return;
+ ioOperations_SetPriority(conn->ops, priority);
+}
+#endif /* WITH_POLICY */
+
const char * connection_GetInterfaceName(const Connection * conn)
{
parcAssertNotNull(conn, "Parameter conn must be non-null");
diff --git a/hicn-light/src/hicn/core/connection.h b/hicn-light/src/hicn/core/connection.h
index b7b5e3c91..3b647dd7a 100644
--- a/hicn-light/src/hicn/core/connection.h
+++ b/hicn-light/src/hicn/core/connection.h
@@ -36,6 +36,7 @@ typedef enum {
CONNECTION_EVENT_UPDATE,
CONNECTION_EVENT_SET_UP,
CONNECTION_EVENT_SET_DOWN,
+ CONNECTION_EVENT_PRIORITY_CHANGED,
} connection_event_t;
#endif /* WITH_MAPME */
@@ -183,6 +184,12 @@ connection_state_t connection_GetAdminState(const Connection *conn);
void connection_SetAdminState(Connection *conn, connection_state_t admin_state);
+#ifdef WITH_POLICY
+uint32_t connection_GetPriority(const Connection *conn);
+
+void connection_SetPriority(Connection *conn, uint32_t priority);
+#endif /* WITH_POLICY */
+
const char * connection_GetInterfaceName(const Connection * conn);
#ifdef WITH_POLICY
diff --git a/hicn-light/src/hicn/core/mapme.c b/hicn-light/src/hicn/core/mapme.c
index 94ada3afa..0eba02e49 100644
--- a/hicn-light/src/hicn/core/mapme.c
+++ b/hicn-light/src/hicn/core/mapme.c
@@ -488,6 +488,7 @@ void mapme_onConnectionEvent(const MapMe *mapme, const Connection *conn_added, c
case CONNECTION_EVENT_DELETE:
case CONNECTION_EVENT_SET_DOWN:
case CONNECTION_EVENT_UPDATE:
+ case CONNECTION_EVENT_PRIORITY_CHANGED:
break;
}
}
diff --git a/hicn-light/src/hicn/io/hicnConnection.c b/hicn-light/src/hicn/io/hicnConnection.c
index d56231c38..e35454438 100644
--- a/hicn-light/src/hicn/io/hicnConnection.c
+++ b/hicn-light/src/hicn/io/hicnConnection.c
@@ -78,6 +78,9 @@ typedef struct hicn_state {
* but it is currently not reachable from within the implementation. */
connection_state_t state;
connection_state_t admin_state;
+#ifdef WITH_POLICY
+ uint32_t priority;
+#endif /* WITH_POLICY */
} _HicnState;
// Prototypes
@@ -97,6 +100,10 @@ static connection_state_t _getState(const IoOperations *ops);
static void _setState(IoOperations *ops, connection_state_t state);
static connection_state_t _getAdminState(const IoOperations *ops);
static void _setAdminState(IoOperations *ops, connection_state_t admin_state);
+#ifdef WITH_POLICY
+static uint32_t _getPriority(const IoOperations *ops);
+static void _setPriority(IoOperations *ops, uint32_t priority);
+#endif /* WITH_POLICY */
static const char * _getInterfaceName(const IoOperations *ops);
/*
@@ -129,6 +136,10 @@ static IoOperations _template = {
.setState = &_setState,
.getAdminState = &_getAdminState,
.setAdminState = &_setAdminState,
+#ifdef WITH_POLICY
+ .getPriority = &_getPriority,
+ .setPriority = &_setPriority,
+#endif /* WITH_POLICY */
.getInterfaceName = &_getInterfaceName,
};
@@ -168,6 +179,10 @@ IoOperations *hicnConnection_Create(Forwarder *forwarder, const char * interface
_setConnectionState(hicnConnState, true);
+#ifdef WITH_POLICY
+ hicnConnState->priority = 0;
+#endif /* WITH_POLICY */
+
if (logger_IsLoggable(hicnConnState->logger, LoggerFacility_IO,
PARCLogLevel_Info)) {
char *str = addressPair_ToString(hicnConnState->addressPair);
@@ -592,6 +607,22 @@ static void _setAdminState(IoOperations *ops, connection_state_t admin_state) {
hicnConnState->admin_state = admin_state;
}
+#ifdef WITH_POLICY
+static uint32_t _getPriority(const IoOperations *ops) {
+ parcAssertNotNull(ops, "Parameter must be non-null");
+ const _HicnState *hicnConnState =
+ (const _HicnState *)ioOperations_GetClosure(ops);
+ return hicnConnState->priority;
+}
+
+static void _setPriority(IoOperations *ops, uint32_t priority) {
+ parcAssertNotNull(ops, "Parameter must be non-null");
+ _HicnState *hicnConnState =
+ (_HicnState *)ioOperations_GetClosure(ops);
+ hicnConnState->priority = priority;
+}
+#endif /* WITH_POLICY
+*/
static const char * _getInterfaceName(const IoOperations *ops)
{
parcAssertNotNull(ops, "Parameter must be non-null");
diff --git a/hicn-light/src/hicn/io/ioOperations.c b/hicn-light/src/hicn/io/ioOperations.c
index b2d346ed8..336e9f12e 100644
--- a/hicn-light/src/hicn/io/ioOperations.c
+++ b/hicn-light/src/hicn/io/ioOperations.c
@@ -86,6 +86,16 @@ void ioOperations_SetAdminState(IoOperations *ops, connection_state_t admin_stat
ops->setAdminState(ops, admin_state);
}
+#ifdef WITH_POLICY
+uint32_t ioOperations_GetPriority(const IoOperations *ops) {
+ return ops->getPriority(ops);
+}
+
+void ioOperations_SetPriority(IoOperations *ops, uint32_t priority) {
+ ops->setPriority(ops, priority);
+}
+#endif /* WITH_POLICY */
+
const char * ioOperations_GetInterfaceName(const IoOperations *ops) {
return ops->getInterfaceName(ops);
}
diff --git a/hicn-light/src/hicn/io/ioOperations.h b/hicn-light/src/hicn/io/ioOperations.h
index c8a107199..ee8720e77 100644
--- a/hicn-light/src/hicn/io/ioOperations.h
+++ b/hicn-light/src/hicn/io/ioOperations.h
@@ -89,6 +89,10 @@ struct io_ops {
void (*setState)(IoOperations *ops, connection_state_t state);
connection_state_t (*getAdminState)(const IoOperations *ops);
void (*setAdminState)(IoOperations *ops, connection_state_t admin_state);
+#ifdef WITH_POLICY
+ uint32_t (*getPriority)(const IoOperations *ops);
+ void (*setPriority)(IoOperations *ops, uint32_t priority);
+#endif /* WITH_POLICY */
const char * (*getInterfaceName)(const IoOperations *ops);
};
@@ -416,6 +420,25 @@ connection_state_t ioOperations_GetAdminState(const IoOperations *ops);
*/
void ioOperations_SetAdminState(IoOperations *ops, connection_state_t admin_state);
+#ifdef WITH_POLICY
+/**
+ * Returns the priority of the connection
+ *
+ * @param [in] ops The connection implementation.
+ *
+ * @return Connection state (uint32_t).
+ */
+uint32_t ioOperations_GetPriority(const IoOperations *ops);
+
+/**
+ * Sets the priority of the connection
+ *
+ * @param [in] ops The connection implementation.
+ * @param [in] state New state to set (uint32_t).
+ */
+void ioOperations_SetPriority(IoOperations *ops, uint32_t priority);
+#endif /* WITH_POLICY */
+
/**
* Sets the interface name associated to the connection.
*
diff --git a/hicn-light/src/hicn/io/streamConnection.c b/hicn-light/src/hicn/io/streamConnection.c
index 4e2f9c37e..27ec45d48 100644
--- a/hicn-light/src/hicn/io/streamConnection.c
+++ b/hicn-light/src/hicn/io/streamConnection.c
@@ -66,6 +66,9 @@ typedef struct stream_state {
* but it is currently not reachable from within the implementation. */
connection_state_t state;
connection_state_t admin_state;
+#ifdef WITH_POLICY
+ uint32_t priority;
+#endif /* WITH_POLICY */
} _StreamState;
// Prototypes
@@ -91,6 +94,10 @@ static connection_state_t _streamConnection_getState(const IoOperations *ops);
static void _streamConnection_setState(IoOperations *ops, connection_state_t state);
static connection_state_t _streamConnection_getAdminState(const IoOperations *ops);
static void _streamConnection_setAdminState(IoOperations *ops, connection_state_t admin_state);
+#ifdef WITH_POLICY
+static uint32_t _streamConnection_getPriority(const IoOperations *ops);
+static void _streamConnection_setPriority(IoOperations *ops, uint32_t priority);
+#endif /* WITH_POLICY */
static const char * _streamConnection_getInterfaceName(const IoOperations *ops);
/*
@@ -123,6 +130,10 @@ static IoOperations _template = {
.setState = &_streamConnection_setState,
.getAdminState = &_streamConnection_getAdminState,
.setAdminState = &_streamConnection_setAdminState,
+#ifdef WITH_POLICY
+ .getPriority = &_streamConnection_getPriority,
+ .setPriority = &_streamConnection_setPriority,
+#endif /* WITH_POLICY */
.getInterfaceName = &_streamConnection_getInterfaceName,
};
@@ -147,6 +158,10 @@ IoOperations *streamConnection_AcceptConnection(Forwarder *forwarder, int fd,
stream->addressPair = pair;
stream->isClosed = false;
+#ifdef WITH_POLICY
+ stream->priority = 0;
+#endif /* WITH_POLICY */
+
// allocate a connection
IoOperations *io_ops = parcMemory_AllocateAndClear(sizeof(IoOperations));
parcAssertNotNull(io_ops, "parcMemory_AllocateAndClear(%zu) returned NULL",
@@ -736,6 +751,22 @@ static void _streamConnection_setAdminState(IoOperations *ops, connection_state_
stream->admin_state = admin_state;
}
+#ifdef WITH_POLICY
+static uint32_t _streamConnection_getPriority(const IoOperations *ops) {
+ parcAssertNotNull(ops, "Parameter must be non-null");
+ const _StreamState *stream =
+ (const _StreamState *)ioOperations_GetClosure(ops);
+ return stream->priority;
+}
+
+static void _streamConnection_setPriority(IoOperations *ops, uint32_t priority) {
+ parcAssertNotNull(ops, "Parameter must be non-null");
+ _StreamState *stream =
+ (_StreamState *)ioOperations_GetClosure(ops);
+ stream->priority = priority;
+}
+#endif /* WITH_POLICY */
+
static const char * _streamConnection_getInterfaceName(const IoOperations *ops)
{
parcAssertNotNull(ops, "Parameter must be non-null");
diff --git a/hicn-light/src/hicn/io/udpConnection.c b/hicn-light/src/hicn/io/udpConnection.c
index 9ad70403f..4e29eba7d 100644
--- a/hicn-light/src/hicn/io/udpConnection.c
+++ b/hicn-light/src/hicn/io/udpConnection.c
@@ -63,6 +63,9 @@ typedef struct udp_state {
* but it is currently not reachable from within the implementation. */
connection_state_t state;
connection_state_t admin_state;
+#ifdef WITH_POLICY
+ uint32_t priority;
+#endif /* WITH_POLICY */
} _UdpState;
// Prototypes
@@ -82,6 +85,10 @@ static connection_state_t _getState(const IoOperations *ops);
static void _setState(IoOperations *ops, connection_state_t state);
static connection_state_t _getAdminState(const IoOperations *ops);
static void _setAdminState(IoOperations *ops, connection_state_t admin_state);
+#ifdef WITH_POLICY
+static uint32_t _getPriority(const IoOperations *ops);
+static void _setPriority(IoOperations *ops, uint32_t priority);
+#endif /* WITH_POLICY */
static const char * _getInterfaceName(const IoOperations *ops);
/*
@@ -114,6 +121,10 @@ static IoOperations _template = {
.setState = &_setState,
.getAdminState = &_getAdminState,
.setAdminState = &_setAdminState,
+#ifdef WITH_POLICY
+ .getPriority = &_getPriority,
+ .setPriority = &_setPriority,
+#endif /* WITH_POLICY */
.getInterfaceName = &_getInterfaceName,
};
@@ -151,6 +162,10 @@ IoOperations *udpConnection_Create(Forwarder *forwarder, const char * interfaceN
_setConnectionState(udpConnState, true);
+#ifdef WITH_POLICY
+ udpConnState->priority = 0;
+#endif /* WITH_POLICY */
+
if (logger_IsLoggable(udpConnState->logger, LoggerFacility_IO,
PARCLogLevel_Info)) {
char *str = addressPair_ToString(udpConnState->addressPair);
@@ -443,6 +458,22 @@ static void _setAdminState(IoOperations *ops, connection_state_t admin_state) {
udpConnState->admin_state = admin_state;
}
+#ifdef WITH_POLICY
+static uint32_t _getPriority(const IoOperations *ops) {
+ parcAssertNotNull(ops, "Parameter must be non-null");
+ const _UdpState *udpConnState =
+ (const _UdpState *)ioOperations_GetClosure(ops);
+ return udpConnState->priority;
+}
+
+static void _setPriority(IoOperations *ops, uint32_t priority) {
+ parcAssertNotNull(ops, "Parameter must be non-null");
+ _UdpState *udpConnState =
+ (_UdpState *)ioOperations_GetClosure(ops);
+ udpConnState->priority = priority;
+}
+#endif /* WITH_POLICY */
+
static const char * _getInterfaceName(const IoOperations *ops)
{
parcAssertNotNull(ops, "Parameter must be non-null");
diff --git a/hicn-light/src/hicn/processor/fibEntry.c b/hicn-light/src/hicn/processor/fibEntry.c
index 1aaa3ace9..11a572c88 100644
--- a/hicn-light/src/hicn/processor/fibEntry.c
+++ b/hicn-light/src/hicn/processor/fibEntry.c
@@ -576,16 +576,39 @@ 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, available_nexthops,
+ out = fibEntry->fwdStrategy->lookupNexthop(fibEntry->fwdStrategy, priority_nexthops,
interestMessage);
} else {
- unsigned nexthop = numberSet_GetItem(available_nexthops, 0);
+ unsigned nexthop = numberSet_GetItem(priority_nexthops, 0);
out = numberSet_Create();
numberSet_Add(out, nexthop);
}
+
+ numberSet_Release(&priority_nexthops);
}
numberSet_Release(&available_nexthops);
diff --git a/hicn-light/src/hicn/utils/commands.h b/hicn-light/src/hicn/utils/commands.h
index a5bc15e8a..520559ccf 100644
--- a/hicn-light/src/hicn/utils/commands.h
+++ b/hicn-light/src/hicn/utils/commands.h
@@ -75,6 +75,7 @@ typedef enum {
LIST_POLICIES,
REMOVE_POLICY,
UPDATE_CONNECTION,
+ CONNECTION_SET_PRIORITY,
#endif /* WITH_POLICY */
LAST_COMMAND_VALUE
} command_id;
@@ -138,6 +139,7 @@ typedef struct {
uint8_t connectionType;
uint8_t admin_state;
#ifdef WITH_POLICY
+ uint32_t priority;
policy_tags_t tags;
#endif /* WITH_POLICY */
} add_connection_command;
@@ -166,6 +168,9 @@ typedef struct {
uint32_t connid;
uint8_t state;
uint8_t admin_state;
+#ifdef WITH_POLICY
+ uint32_t priority;
+#endif /* WITH_POLICY */
char interfaceName[SYMBOLIC_NAME_LEN];
char connectionName[SYMBOLIC_NAME_LEN];
} list_connections_command;
@@ -335,9 +340,15 @@ typedef struct {
typedef struct {
char symbolicOrConnid[SYMBOLIC_NAME_LEN];
uint8_t admin_state;
+ uint32_t priority;
policy_tags_t tags;
} update_connection_command;
+typedef struct {
+ char symbolicOrConnid[SYMBOLIC_NAME_LEN];
+ uint32_t priority;
+} connection_set_priority_command;
+
#endif /* WITH_POLICY */
//===== size of commands ======
@@ -394,6 +405,8 @@ static inline int payloadLengthDaemon(command_id id) {
return sizeof(remove_policy_command);
case UPDATE_CONNECTION:
return sizeof(update_connection_command);
+ case CONNECTION_SET_PRIORITY:
+ return sizeof(connection_set_priority_command);
#endif /* WITH_POLICY */
case LAST_COMMAND_VALUE:
return 0;
diff --git a/hicn-plugin/src/error.h b/hicn-plugin/src/error.h
index 0abcce96c..14cec0a3f 100644
--- a/hicn-plugin/src/error.h
+++ b/hicn-plugin/src/error.h
@@ -74,7 +74,7 @@
_(APPFACE_FEATURE, -181, "Error while enabling app face feature") \
_(APPFACE_NOT_FOUND, -182, "Application face not found") \
_(APPFACE_PROD_PREFIX_NULL, -183, "Prefix must not be null for producer face") \
- _(STRATEGY_NH_NOT_FOUND, -184, "Next hop not found") \
+ _(STRATEGY_NH_NOT_FOUND, -184, "Next hop not found") \
_(MW_STRATEGY_SET, -185, "Error while setting weight for next hop") \
_(STRATEGY_NOT_FOUND, -186, "Strategy not found")
diff --git a/hicn-plugin/src/faces/udp/face_udp.c b/hicn-plugin/src/faces/udp/face_udp.c
index 751065f82..ec43d9081 100644
--- a/hicn-plugin/src/faces/udp/face_udp.c
+++ b/hicn-plugin/src/faces/udp/face_udp.c
@@ -366,7 +366,7 @@ format_hicn_face_udp (u8 * s, va_list * args)
format_ip6_address, &udp_face->hdrs.ip6.ip.src_address,
clib_net_to_host_u16 (udp_face->hdrs.ip6.udp.src_port));
s =
- format (s, "remote %U|%u", format_ip6_address,
+ format (s, "remote %U|%u ", format_ip6_address,
&udp_face->hdrs.ip6.ip.dst_address,
clib_net_to_host_u16 (udp_face->hdrs.ip6.udp.dst_port));
s = format (s, "%U", format_vnet_link, adj->ia_link);
diff --git a/hicn-plugin/src/hicn.api b/hicn-plugin/src/hicn.api
index 4f3047b0a..9a194b97f 100644
--- a/hicn-plugin/src/hicn.api
+++ b/hicn-plugin/src/hicn.api
@@ -16,6 +16,56 @@
option version = "5.1.0";
import "vnet/ip/ip_types.api";
+enum face_type : u8 {
+ IP_FACE = 0,
+ UDP_FACE,
+};
+
+typedef hicn_face_ip {
+ /* IP local address */
+ vl_api_address_t local_addr;
+
+ /* IP remote address */
+ vl_api_address_t remote_addr;
+
+ /* IPv4 local port number */
+ u32 swif;
+
+ /* Face flags */
+ u32 flags;
+
+ /* Name of the interface */
+ u8 if_name[30];
+};
+
+typedef hicn_face_udp {
+ /* IP local address */
+ vl_api_address_t local_addr;
+
+ /* IP remote address */
+ vl_api_address_t remote_addr;
+
+ /* Local port */
+ u16 lport;
+
+ /* Remote port */
+ u16 rport;
+
+ /* IPv4 local port number */
+ u32 swif;
+
+ /* Face flags */
+ u32 flags;
+
+ /* Name of the interface */
+ u8 if_name[30];
+};
+
+typedef hicn_face_union {
+ vl_api_hicn_face_ip_t ip;
+ vl_api_hicn_face_udp_t udp;
+};
+
define hicn_api_node_params_set
{
/* Client identifier, set from api_main.my_client_index */
@@ -160,13 +210,7 @@ define hicn_api_face_ip_add
u32 context;
/* IP local address */
- vl_api_address_t local_addr;
-
- /* IP remote address */
- vl_api_address_t remote_addr;
-
- /* IPv4 local port number */
- u32 swif;
+ vl_api_hicn_face_ip_t face;
};
define hicn_api_face_ip_add_reply
@@ -202,18 +246,6 @@ define hicn_api_face_ip_del_reply
i32 retval;
};
-define hicn_api_face_ip_params_get
-{
- /* Client identifier, set from api_main.my_client_index */
- u32 client_index;
-
- /* Arbitrary context, so client can match reply to request */
- u32 context;
-
- /* A Face to be retrieved */
- u32 faceid;
-};
-
define hicn_api_face_stats_details
{
/* From the request */
@@ -255,6 +287,18 @@ define hicn_api_face_stats_dump
u32 context;
};
+define hicn_api_face_ip_params_get
+{
+ /* Client identifier, set from api_main.my_client_index */
+ u32 client_index;
+
+ /* Arbitrary context, so client can match reply to request */
+ u32 context;
+
+ /* A Face to be retrieved */
+ u32 faceid;
+};
+
define hicn_api_face_ip_params_get_reply
{
/* From the request */
@@ -279,6 +323,111 @@ define hicn_api_face_ip_params_get_reply
u32 flags;
};
+define hicn_api_face_add
+{
+ /* Client identifier, set from api_main.my_client_index */
+ u32 client_index;
+
+ /* Arbitrary context, so client can match reply to request */
+ u32 context;
+
+ /* Type of face to add */
+ vl_api_face_type_t type;
+
+ /* Face to add */
+ vl_api_hicn_face_union_t face;
+};
+
+define hicn_api_face_add_reply
+{
+ /* From the request */
+ u32 context;
+
+ /* Return value: new Face ID, ~0 means no Face was created */
+ u32 faceid;
+
+ /* Return value, zero means all OK */
+ i32 retval;
+};
+
+define hicn_api_face_del
+{
+ /* Client identifier, set from api_main.my_client_index */
+ u32 client_index;
+
+ /* Arbitrary context, so client can match reply to request */
+ u32 context;
+
+ /* A Face ID to be deleted */
+ u32 faceid;
+};
+
+define hicn_api_face_del_reply
+{
+ /* From the request */
+ u32 context;
+
+ /* Return value, zero means all OK */
+ i32 retval;
+};
+
+define hicn_api_faces_details
+{
+/* From the request */
+ u32 context;
+
+ /* Return value, zero means all OK */
+ i32 retval;
+
+ /* Id of the face */
+ u32 faceid;
+
+ /* Type of face to add */
+ vl_api_face_type_t type;
+
+ /* Face to add */
+ vl_api_hicn_face_union_t face;
+};
+
+define hicn_api_faces_dump
+{
+/* Client identifier, set from api_main.my_client_index */
+ u32 client_index;
+
+ /* Arbitrary context, so client can match reply to request */
+ u32 context;
+};
+
+define hicn_api_face_get
+{
+ /* Client identifier, set from api_main.my_client_index */
+ u32 client_index;
+
+ /* Arbitrary context, so client can match reply to request */
+ u32 context;
+
+ /* A Face to be retrieved */
+ u32 faceid;
+};
+
+define hicn_api_face_get_reply
+{
+ /* From the request */
+ u32 context;
+
+ /* Return value, zero means all OK */
+ i32 retval;
+
+ /* Id of the face */
+ u32 faceid;
+
+ /* Type of face to add */
+ vl_api_face_type_t type;
+
+ /* Face to add */
+ vl_api_hicn_face_union_t face;
+};
+
define hicn_api_route_nhops_add
{
/* Client identifier, set from api_main.my_client_index */
diff --git a/hicn-plugin/src/hicn_api.c b/hicn-plugin/src/hicn_api.c
index 5f195b6da..b1e6bccb9 100644
--- a/hicn-plugin/src/hicn_api.c
+++ b/hicn-plugin/src/hicn_api.c
@@ -26,6 +26,7 @@
#include "hicn.h"
#include "faces/ip/face_ip.h"
+#include "faces/udp/face_udp.h"
#include "infra.h"
#include "parser.h"
#include "mgmt.h"
@@ -70,6 +71,10 @@
_(HICN_API_FACE_IP_ADD, hicn_api_face_ip_add) \
_(HICN_API_FACE_IP_DEL, hicn_api_face_ip_del) \
_(HICN_API_FACE_IP_PARAMS_GET, hicn_api_face_ip_params_get) \
+ _(HICN_API_FACE_ADD, hicn_api_face_add) \
+ _(HICN_API_FACE_DEL, hicn_api_face_del) \
+ _(HICN_API_FACES_DUMP, hicn_api_faces_dump) \
+ _(HICN_API_FACE_GET, hicn_api_face_get) \
_(HICN_API_FACE_STATS_DUMP, hicn_api_face_stats_dump) \
_(HICN_API_ROUTE_GET, hicn_api_route_get) \
_(HICN_API_ROUTES_DUMP, hicn_api_routes_dump) \
@@ -175,21 +180,17 @@ vl_api_hicn_api_node_stats_get_t_handler (vl_api_hicn_api_node_stats_get_t *
/****** FACE *******/
-
-static void
-vl_api_hicn_api_face_ip_add_t_handler (vl_api_hicn_api_face_ip_add_t * mp)
+static hicn_error_t
+hicn_api_face_ip_add (vl_api_hicn_face_ip_t * mp, hicn_face_id_t * face_id)
{
- vl_api_hicn_api_face_ip_add_reply_t *rmp;
hicn_error_t rv = HICN_ERROR_NONE;
- hicn_main_t *sm = &hicn_main;
vnet_main_t *vnm = vnet_get_main ();
- hicn_face_id_t faceid = HICN_FACE_NULL;
ip46_address_t local_addr;
ip46_address_t remote_addr;
- ip_address_decode(&mp->local_addr, &local_addr);
- ip_address_decode(&mp->remote_addr, &remote_addr);
+ ip_address_decode (&mp->local_addr, &local_addr);
+ ip_address_decode (&mp->remote_addr, &remote_addr);
u32 sw_if = clib_net_to_host_u32 (mp->swif);
@@ -244,14 +245,25 @@ vl_api_hicn_api_face_ip_add_t_handler (vl_api_hicn_api_face_ip_add_t * mp)
}
if (rv == HICN_ERROR_NONE)
- rv = hicn_face_ip_add (&local_addr, &remote_addr, sw_if, &faceid, 0);
- else
- faceid = HICN_FACE_NULL;
+ rv = hicn_face_ip_add (&local_addr, &remote_addr, sw_if, face_id, 0);
+
+ return rv;
+}
+
+static void
+vl_api_hicn_api_face_ip_add_t_handler (vl_api_hicn_api_face_ip_add_t * mp)
+{
+ vl_api_hicn_api_face_ip_add_reply_t *rmp;
+ hicn_error_t rv = HICN_ERROR_NONE;
+
+ hicn_main_t *sm = &hicn_main;
+ hicn_face_id_t face_id = HICN_FACE_NULL;
+ rv = hicn_api_face_ip_add (&(mp->face), &face_id);
/* *INDENT-OFF* */
REPLY_MACRO2 (VL_API_HICN_API_FACE_IP_ADD_REPLY /* , rmp, mp, rv */ ,(
{
- rmp->faceid = clib_host_to_net_u32 ((u32) faceid);
+ rmp->faceid = clib_host_to_net_u32 ((u32) face_id);
rmp->retval = rv;
}));
/* *INDENT-ON* */
@@ -261,12 +273,15 @@ static void
vl_api_hicn_api_face_ip_del_t_handler (vl_api_hicn_api_face_ip_del_t * mp)
{
vl_api_hicn_api_face_ip_del_reply_t *rmp;
- int rv = HICN_ERROR_NONE;
+ int rv = HICN_ERROR_FACE_NOT_FOUND;
hicn_main_t *sm = &hicn_main;
hicn_face_id_t faceid = clib_net_to_host_u32 (mp->faceid);
- rv = hicn_face_ip_del (faceid);
+ if (hicn_dpoi_idx_is_valid (faceid))
+ {
+ rv = hicn_face_ip_del (faceid);
+ }
REPLY_MACRO (VL_API_HICN_API_FACE_IP_DEL_REPLY /* , rmp, mp, rv */ );
@@ -292,6 +307,242 @@ static void
/* *INDENT-ON* */
}
+static hicn_error_t
+hicn_api_face_udp_add (vl_api_hicn_face_udp_t * mp, hicn_face_id_t * face_id)
+{
+ hicn_error_t rv = HICN_ERROR_NONE;
+
+ ip46_address_t local_addr = ip46_address_initializer;
+ ip46_address_t remote_addr = ip46_address_initializer;
+ u16 lport;
+ u16 rport;
+ u32 sw_if;
+ ip_address_decode (&mp->local_addr, &local_addr);
+ ip_address_decode (&mp->remote_addr, &remote_addr);
+ //Do not byteswap. We store ports in network order
+ lport = mp->lport;
+ rport = mp->rport;
+ sw_if = clib_net_to_host_u32 (mp->swif);
+
+ int input_is_ok = !ip46_address_is_zero (&local_addr)
+ && !ip46_address_is_zero (&remote_addr)
+ &&
+ ((ip46_address_is_ip4 (&local_addr) && ip46_address_is_ip4 (&remote_addr))
+ || (!ip46_address_is_ip4 (&local_addr)
+ && !ip46_address_is_ip4 (&remote_addr))) && lport != 0 && rport != 0;
+
+ if (!input_is_ok)
+ {
+ rv = HICN_ERROR_UNSPECIFIED;
+ }
+ else
+ {
+ rv = hicn_face_udp_add (&local_addr,
+ &remote_addr, lport, rport, sw_if, face_id);
+ }
+ return rv;
+}
+
+static void
+vl_api_hicn_api_face_add_t_handler (vl_api_hicn_api_face_add_t * mp)
+{
+ vl_api_hicn_api_face_add_reply_t *rmp;
+ hicn_error_t rv = HICN_ERROR_NONE;
+
+ hicn_main_t *sm = &hicn_main;
+ hicn_face_id_t face_id;
+ vl_api_face_type_t face_type = mp->type;
+
+ switch (face_type)
+ {
+ case IP_FACE:
+ rv = hicn_api_face_ip_add (&(mp->face.ip), &face_id);
+ break;
+ case UDP_FACE:
+ rv = hicn_api_face_udp_add (&(mp->face.udp), &face_id);
+ break;
+ default:
+ rv = HICN_ERROR_UNSPECIFIED;
+ break;
+ }
+
+ /* *INDENT-OFF* */
+ REPLY_MACRO2 (VL_API_HICN_API_FACE_ADD_REPLY /* , rmp, mp, rv */ ,(
+ {
+ rmp->faceid = clib_host_to_net_u32 ((u32) face_id);
+ rmp->retval = rv;
+ }));
+ /* *INDENT-ON* */
+}
+
+static void
+vl_api_hicn_api_face_del_t_handler (vl_api_hicn_api_face_del_t * mp)
+{
+ vl_api_hicn_api_face_del_reply_t *rmp;
+ int rv = HICN_ERROR_FACE_NOT_FOUND;
+
+ hicn_main_t *sm = &hicn_main;
+
+ hicn_face_id_t faceid = clib_net_to_host_u32 (mp->faceid);
+ if (hicn_dpoi_idx_is_valid (faceid))
+ {
+ hicn_face_t *face = hicn_dpoi_get_from_idx (faceid);
+ hicn_face_vft_t *vft = hicn_face_get_vft (face->shared.face_type);
+ rv = vft->hicn_face_del (faceid);
+ }
+
+ REPLY_MACRO (VL_API_HICN_API_FACE_DEL_REPLY /* , rmp, mp, rv */ );
+
+}
+
+static void
+send_face_ip_details (hicn_face_t * face, vl_api_hicn_face_ip_t * mp)
+{
+ vnet_main_t *vnm = vnet_get_main ();
+
+ hicn_face_ip_t *face_ip = (hicn_face_ip_t *) face->data;
+ ip_address_encode (&face_ip->local_addr, IP46_TYPE_ANY, &mp->local_addr);
+ ip_address_encode (&face_ip->remote_addr, IP46_TYPE_ANY, &mp->remote_addr);
+ mp->flags = clib_host_to_net_u32 (face->shared.flags);
+ mp->swif = clib_net_to_host_u32 (face->shared.sw_if);
+ vnet_sw_interface_t *sw_interface =
+ vnet_get_sw_interface_or_null (vnm, face->shared.sw_if);
+ u8 *sbuf = 0;
+ if (sw_interface != NULL)
+ {
+ sbuf =
+ format (0, "%U", format_vnet_sw_interface_name, vnm, sw_interface);
+ strcpy ((char *) (mp->if_name), (char *) sbuf);
+ }
+}
+
+static void
+send_face_udp_details (hicn_face_t * face, vl_api_hicn_face_udp_t * mp)
+{
+ vnet_main_t *vnm = vnet_get_main ();
+ hicn_face_udp_t *face_udp = (hicn_face_udp_t *) face->data;
+ if (face_udp->hdrs.ip4.ip.ip_version_and_header_length == 0x45)
+ {
+ ip46_address_t src_addr = { 0 };
+ ip46_address_t dst_addr = { 0 };
+ ip46_address_set_ip4 (&src_addr, &(face_udp->hdrs.ip4.ip.src_address));
+ ip46_address_set_ip4 (&dst_addr, &(face_udp->hdrs.ip4.ip.dst_address));
+
+ ip_address_encode (&src_addr, IP46_TYPE_ANY, &(mp->local_addr));
+ ip_address_encode (&dst_addr, IP46_TYPE_ANY, &(mp->remote_addr));
+ //Do not swap, they are already in network order
+ mp->lport = face_udp->hdrs.ip4.udp.src_port;
+ mp->rport = face_udp->hdrs.ip4.udp.dst_port;
+ }
+ else
+ {
+ ip46_address_t src_addr = { 0 };
+ ip46_address_t dst_addr = { 0 };
+ ip46_address_set_ip6 (&src_addr, &(face_udp->hdrs.ip6.ip.src_address));
+ ip46_address_set_ip6 (&dst_addr, &(face_udp->hdrs.ip6.ip.dst_address));
+
+ ip_address_encode (&src_addr, IP46_TYPE_ANY, &(mp->local_addr));
+ ip_address_encode (&dst_addr, IP46_TYPE_ANY, &(mp->remote_addr));
+ //Do not swap, they are already in network order
+ mp->lport = face_udp->hdrs.ip6.udp.src_port;
+ mp->rport = face_udp->hdrs.ip6.udp.dst_port;
+ }
+ mp->flags = clib_host_to_net_u32 (face->shared.flags);
+ mp->swif = clib_net_to_host_u32 (face->shared.sw_if);
+ vnet_sw_interface_t *sw_interface =
+ vnet_get_sw_interface_or_null (vnm, face->shared.sw_if);
+ u8 *sbuf = 0;
+ if (sw_interface != NULL)
+ {
+ sbuf =
+ format (0, "%U", format_vnet_sw_interface_name, vnm, sw_interface);
+ strcpy ((char *) (mp->if_name), (char *) sbuf);
+ }
+}
+
+static void
+send_faces_details (vl_api_registration_t * reg,
+ hicn_face_t * face, u32 context)
+{
+ vl_api_hicn_api_faces_details_t *mp;
+ hicn_main_t *hm = &hicn_main;
+ mp = vl_msg_api_alloc (sizeof (*mp));
+ memset (mp, 0, sizeof (*mp));
+ mp->faceid = clib_host_to_net_u32 (hicn_dpoi_get_index (face));
+ mp->_vl_msg_id = htons (VL_API_HICN_API_FACES_DETAILS + hm->msg_id_base);
+ mp->context = context;
+
+ if (face->shared.face_type == hicn_face_ip_type)
+ {
+ mp->type = IP_FACE;
+ send_face_ip_details (face, &(mp->face.ip));
+ }
+ else if (face->shared.face_type == hicn_face_udp_type)
+ {
+ mp->type = UDP_FACE;
+ send_face_udp_details (face, &(mp->face.udp));
+ }
+
+
+ vl_api_send_msg (reg, (u8 *) mp);
+}
+
+static void
+ vl_api_hicn_api_faces_dump_t_handler (vl_api_hicn_api_faces_dump_t * mp)
+{
+ hicn_face_t *face;
+ vl_api_registration_t *reg;
+
+ reg = vl_api_client_index_to_registration (mp->client_index);
+ if (!reg)
+ return;
+
+ /* *INDENT-OFF* */
+ pool_foreach (face, hicn_dpoi_face_pool,
+ ({
+ send_faces_details (reg, face, mp->context);
+ }));
+ /* *INDENT-ON* */
+}
+
+static void
+ vl_api_hicn_api_face_get_t_handler (vl_api_hicn_api_face_get_t * mp)
+{
+ vl_api_hicn_api_face_get_reply_t *rmp;
+ int rv = 0;
+
+ hicn_main_t *sm = &hicn_main;
+
+ hicn_face_id_t faceid = clib_net_to_host_u32 (mp->faceid);
+
+ /* *INDENT-OFF* */
+ REPLY_MACRO2 (VL_API_HICN_API_FACE_GET_REPLY, (
+ {
+ rv = hicn_dpoi_idx_is_valid(faceid);
+ if (rv)
+ {
+ hicn_face_t * face = hicn_dpoi_get_from_idx(faceid);
+ if (face->shared.face_type == hicn_face_ip_type)
+ {
+ rmp->type = IP_FACE;
+ send_face_ip_details(face, &(rmp->face.ip));
+ }
+ else if (face->shared.face_type == hicn_face_udp_type)
+ {
+ rmp->type = UDP_FACE;
+ send_face_udp_details(face, &(rmp->face.udp));
+ }
+ rv = HICN_ERROR_NONE;
+ }
+ else
+ {
+ rv = HICN_ERROR_FACE_NOT_FOUND;
+ }
+ rmp->retval = clib_host_to_net_u32(rv);
+ }));
+ /* *INDENT-ON* */
+}
+
static void
send_face_stats_details (vl_api_registration_t * reg,
hicn_face_t * face, u32 context)
@@ -367,7 +618,7 @@ vl_api_hicn_api_route_nhops_add_t_handler (vl_api_hicn_api_route_nhops_add_t
hicn_main_t *sm = &hicn_main;
fib_prefix_t prefix;
- ip_prefix_decode(&mp->prefix, &prefix);
+ ip_prefix_decode (&mp->prefix, &prefix);
u8 n_faces = mp->n_faces;
@@ -402,7 +653,7 @@ static void vl_api_hicn_api_route_del_t_handler
hicn_main_t *sm = &hicn_main;
fib_prefix_t prefix;
- ip_prefix_decode(&mp->prefix, &prefix);
+ ip_prefix_decode (&mp->prefix, &prefix);
rv = hicn_route_del (&prefix);
@@ -418,7 +669,7 @@ static void vl_api_hicn_api_route_nhop_del_t_handler
hicn_main_t *sm = &hicn_main;
fib_prefix_t prefix;
- ip_prefix_decode(&mp->prefix, &prefix);
+ ip_prefix_decode (&mp->prefix, &prefix);
hicn_face_id_t faceid = clib_net_to_host_u32 (mp->faceid);
@@ -436,7 +687,7 @@ static void vl_api_hicn_api_route_get_t_handler
hicn_main_t *sm = &hicn_main;
fib_prefix_t prefix;
- ip_prefix_decode(&mp->prefix, &prefix);
+ ip_prefix_decode (&mp->prefix, &prefix);
const dpo_id_t *hicn_dpo_id;
const hicn_dpo_vft_t *hicn_dpo_vft;
hicn_dpo_ctx_t *hicn_dpo_ctx;
@@ -482,8 +733,7 @@ send_route_details (vl_api_registration_t * reg,
hicn_dpo_ctx_t *hicn_dpo_ctx;
u32 fib_index;
- int rv =
- hicn_route_get_dpo (pfx, &hicn_dpo_id, &fib_index);
+ int rv = hicn_route_get_dpo (pfx, &hicn_dpo_id, &fib_index);
if (rv == HICN_ERROR_NONE)
{
@@ -494,8 +744,9 @@ send_route_details (vl_api_registration_t * reg,
if (dpo_id_is_valid (&hicn_dpo_ctx->next_hops[i]))
{
mp->faceids[i] =
- clib_host_to_net_u32 (((dpo_id_t *) & hicn_dpo_ctx->
- next_hops[i])->dpoi_index);
+ clib_host_to_net_u32 (((dpo_id_t *) &
+ hicn_dpo_ctx->next_hops[i])->
+ dpoi_index);
mp->nfaces++;
}
}
@@ -566,7 +817,8 @@ static void
fib_table_walk (fib_table->ft_index,
FIB_PROTOCOL_IP4,
vl_api_hicn_api_route_dump_walk,
- &ctx);}
+ &ctx);
+ }
));
pool_foreach (fib_table, im6->fibs, (
@@ -574,7 +826,8 @@ static void
fib_table_walk (fib_table->ft_index,
FIB_PROTOCOL_IP6,
vl_api_hicn_api_route_dump_walk,
- &ctx);}
+ &ctx);
+ }
));
vec_foreach (lfeip, ctx.feis)
@@ -647,11 +900,10 @@ static void vl_api_hicn_api_punting_add_t_handler
hicn_main_t *sm = &hicn_main;
fib_prefix_t prefix;
- ip_prefix_decode(&mp->prefix, &prefix);
+ ip_prefix_decode (&mp->prefix, &prefix);
u32 swif = clib_net_to_host_u32 (mp->swif);
- rv =
- hicn_punt_interest_data_for_ip (vm, &prefix, swif, 0, NO_L2);
+ rv = hicn_punt_interest_data_for_ip (vm, &prefix, swif, 0, NO_L2);
REPLY_MACRO (VL_API_HICN_API_PUNTING_ADD_REPLY /* , rmp, mp, rv */ );
}
@@ -680,7 +932,7 @@ static void vl_api_hicn_api_register_prod_app_t_handler
hicn_main_t *sm = &hicn_main;
fib_prefix_t prefix;
- ip_prefix_decode(&mp->prefix, &prefix);
+ ip_prefix_decode (&mp->prefix, &prefix);
u32 swif = clib_net_to_host_u32 (mp->swif);
u32 cs_reserved = clib_net_to_host_u32 (mp->cs_reserved);
u32 faceid;
@@ -797,8 +1049,10 @@ hicn_face_api_entry_params_serialize (hicn_face_id_t faceid,
if (face != NULL && face->shared.face_type == hicn_face_ip_type)
{
hicn_face_ip_t *face_ip = (hicn_face_ip_t *) face->data;
- ip_address_encode(&face_ip->local_addr, IP46_TYPE_ANY, &reply->local_addr);
- ip_address_encode(&face_ip->remote_addr, IP46_TYPE_ANY, &reply->remote_addr);
+ ip_address_encode (&face_ip->local_addr, IP46_TYPE_ANY,
+ &reply->local_addr);
+ ip_address_encode (&face_ip->remote_addr, IP46_TYPE_ANY,
+ &reply->remote_addr);
reply->swif = clib_host_to_net_u32 (face->shared.sw_if);
reply->flags = clib_host_to_net_u32 (face->shared.flags);
reply->faceid = clib_host_to_net_u32 (faceid);
diff --git a/hicn-plugin/src/hicn_api_test.c b/hicn-plugin/src/hicn_api_test.c
index c29aa4a21..fa0e075f8 100644
--- a/hicn-plugin/src/hicn_api_test.c
+++ b/hicn-plugin/src/hicn_api_test.c
@@ -84,69 +84,94 @@ unformat_ip46_address (unformat_input_t * input, va_list * args)
return 0;
}
-/* static ip46_type_t */
-/* ip_address_union_decode (const vl_api_address_union_t *in, */
-/* vl_api_address_family_t af, */
-/* ip46_address_t *out) */
-/* { */
-/* ip46_type_t type; */
-
-/* switch (clib_net_to_host_u32 (af)) */
-/* { */
-/* case ADDRESS_IP4: */
-/* clib_memset (out, 0, sizeof (*out)); */
-/* clib_memcpy (&out->ip4, &in->ip4, sizeof (out->ip4)); */
-/* type = IP46_TYPE_IP4; */
-/* break; */
-/* case ADDRESS_IP6: */
-/* clib_memcpy (&out->ip6, &in->ip6, sizeof (out->ip6)); */
-/* type = IP46_TYPE_IP6; */
-/* break; */
-/* default: */
-/* ASSERT (!"Unkown address family in API address type"); */
-/* type = IP46_TYPE_ANY; */
-/* break; */
-/* } */
-
-/* return type; */
-/* } */
-
-/* static void */
-/* ip_address_union_encode (const ip46_address_t * in, */
-/* vl_api_address_family_t af, */
-/* vl_api_address_union_t * out) */
-/* { */
-/* if (ADDRESS_IP6 == clib_net_to_host_u32 (af)) */
-/* memcpy (out->ip6.address, &in->ip6, sizeof (out->ip6)); */
-/* else */
-/* memcpy (out->ip4.address, &in->ip4, sizeof (out->ip4)); */
-/* } */
-
-/* ip46_type_t ip_address_decode (const vl_api_address_t *in, ip46_address_t *out) */
-/* { */
-/* return (ip_address_union_decode (&in->un, in->af, out)); */
-/* } */
-
-/* void ip_address_encode (const ip46_address_t *in, ip46_type_t type, */
-/* vl_api_address_t *out) */
-/* { */
-/* switch (type) */
-/* { */
-/* case IP46_TYPE_IP4: */
-/* out->af = clib_net_to_host_u32 (ADDRESS_IP4); */
-/* break; */
-/* case IP46_TYPE_IP6: */
-/* out->af = clib_net_to_host_u32 (ADDRESS_IP6); */
-/* break; */
-/* case IP46_TYPE_ANY: */
-/* if (ip46_address_is_ip4 (in)) */
-/* out->af = clib_net_to_host_u32 (ADDRESS_IP4); */
-/* else */
-/* out->af = clib_net_to_host_u32 (ADDRESS_IP6); */
-/* break; */
-/* } */
-/* ip_address_union_encode (in, out->af, &out->un); */
-/* } */
+static ip46_type_t
+ip_address_union_decode (const vl_api_address_union_t * in,
+ vl_api_address_family_t af, ip46_address_t * out)
+{
+ ip46_type_t type;
+
+ switch (clib_net_to_host_u32 (af))
+ {
+ case ADDRESS_IP4:
+ clib_memset (out, 0, sizeof (*out));
+ clib_memcpy (&out->ip4, &in->ip4, sizeof (out->ip4));
+ type = IP46_TYPE_IP4;
+ break;
+ case ADDRESS_IP6:
+ clib_memcpy (&out->ip6, &in->ip6, sizeof (out->ip6));
+ type = IP46_TYPE_IP6;
+ break;
+ default:
+ ASSERT (!"Unkown address family in API address type");
+ type = IP46_TYPE_ANY;
+ break;
+ }
+
+ return type;
+}
+
+void
+ip6_address_encode (const ip6_address_t * in, vl_api_ip6_address_t out)
+{
+ clib_memcpy (out, in, sizeof (*in));
+}
+
+void
+ip6_address_decode (const vl_api_ip6_address_t in, ip6_address_t * out)
+{
+ clib_memcpy (out, in, sizeof (*out));
+}
+
+void
+ip4_address_encode (const ip4_address_t * in, vl_api_ip4_address_t out)
+{
+ clib_memcpy (out, in, sizeof (*in));
+}
+
+void
+ip4_address_decode (const vl_api_ip4_address_t in, ip4_address_t * out)
+{
+ clib_memcpy (out, in, sizeof (*out));
+}
+
+static void
+ip_address_union_encode (const ip46_address_t * in,
+ vl_api_address_family_t af,
+ vl_api_address_union_t * out)
+{
+ if (ADDRESS_IP6 == clib_net_to_host_u32 (af))
+ ip6_address_encode (&in->ip6, out->ip6);
+ else
+ ip4_address_encode (&in->ip4, out->ip4);
+}
+
+ip46_type_t
+ip_address_decode (const vl_api_address_t * in, ip46_address_t * out)
+{
+ return (ip_address_union_decode (&in->un, in->af, out));
+}
+
+void
+ip_address_encode (const ip46_address_t * in, ip46_type_t type,
+ vl_api_address_t * out)
+{
+ switch (type)
+ {
+ case IP46_TYPE_IP4:
+ out->af = clib_net_to_host_u32 (ADDRESS_IP4);
+ break;
+ case IP46_TYPE_IP6:
+ out->af = clib_net_to_host_u32 (ADDRESS_IP6);
+ break;
+ case IP46_TYPE_ANY:
+ if (ip46_address_is_ip4 (in))
+ out->af = clib_net_to_host_u32 (ADDRESS_IP4);
+ else
+ out->af = clib_net_to_host_u32 (ADDRESS_IP6);
+ break;
+ }
+ ip_address_union_encode (in, out->af, &out->un);
+}
/////////////////////////////////////////////////////
@@ -165,6 +190,7 @@ hicn_test_main_t hicn_test_main;
#define foreach_standard_reply_retval_handler \
_(hicn_api_node_params_set_reply) \
_(hicn_api_face_ip_del_reply) \
+_(hicn_api_face_del_reply) \
_(hicn_api_route_nhops_add_reply) \
_(hicn_api_route_del_reply) \
_(hicn_api_route_nhop_del_reply)
@@ -196,6 +222,10 @@ _(HICN_API_NODE_PARAMS_GET_REPLY, hicn_api_node_params_get_reply) \
_(HICN_API_NODE_STATS_GET_REPLY, hicn_api_node_stats_get_reply) \
_(HICN_API_FACE_IP_DEL_REPLY, hicn_api_face_ip_del_reply) \
_(HICN_API_FACE_IP_ADD_REPLY, hicn_api_face_ip_add_reply) \
+_(HICN_API_FACE_ADD_REPLY, hicn_api_face_add_reply) \
+_(HICN_API_FACE_DEL_REPLY, hicn_api_face_del_reply) \
+_(HICN_API_FACE_GET_REPLY, hicn_api_face_get_reply) \
+_(HICN_API_FACES_DETAILS, hicn_api_faces_details) \
_(HICN_API_FACE_STATS_DETAILS, hicn_api_face_stats_details) \
_(HICN_API_ROUTE_NHOPS_ADD_REPLY, hicn_api_route_nhops_add_reply) \
_(HICN_API_FACE_IP_PARAMS_GET_REPLY, hicn_api_face_ip_params_get_reply) \
@@ -393,22 +423,18 @@ api_hicn_api_face_ip_add (vat_main_t * vam)
ip46_address_t remote_addr = { 0 };
int ret = HICN_ERROR_NONE;
int sw_if = 0;
- vl_api_hicn_api_face_ip_add_t *mp;
+ vl_api_hicn_api_face_add_t *mp;
/* Parse args required to build the message */
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
{
if (unformat
- (input, "local %U", unformat_ip4_address, &local_addr.ip4));
- else
- if (unformat
- (input, "local %U", unformat_ip6_address, &local_addr.ip6));
- else
- if (unformat
- (input, "remote %U", unformat_ip4_address, &remote_addr.ip4));
+ (input, "local %U", unformat_ip46_address, &local_addr,
+ IP46_TYPE_ANY));
else
if (unformat
- (input, "remote %U", unformat_ip6_address, &remote_addr.ip6));
+ (input, "remote %U", unformat_ip46_address, &remote_addr,
+ IP46_TYPE_ANY));
else if (unformat (input, "intfc %d", &sw_if));
else
{
@@ -423,10 +449,11 @@ api_hicn_api_face_ip_add (vat_main_t * vam)
return (1);
}
/* Construct the API message */
- M (HICN_API_FACE_IP_ADD, mp);
- ip_address_decode (&mp->local_addr, &local_addr);
- ip_address_decode (&mp->remote_addr, &remote_addr);
- mp->swif = clib_host_to_net_u32 (sw_if);
+ M (HICN_API_FACE_ADD, mp);
+ mp->type = IP_FACE;
+ ip_address_encode (&local_addr, IP46_TYPE_ANY, &mp->face.ip.local_addr);
+ ip_address_encode (&remote_addr, IP46_TYPE_ANY, &mp->face.ip.remote_addr);
+ mp->face.ip.swif = clib_host_to_net_u32 (sw_if);
/* send it... */
S (mp);
@@ -462,6 +489,85 @@ static void
}
static int
+api_hicn_api_face_udp_add (vat_main_t * vam)
+{
+ unformat_input_t *input = vam->input;
+ ip46_address_t local_addr = ip46_address_initializer;
+ ip46_address_t remote_addr = ip46_address_initializer;
+ u32 sport = 0;
+ u32 dport = 0;
+ int ret = HICN_ERROR_NONE;
+ int sw_if = ~0;
+ vl_api_hicn_api_face_add_t *mp;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat
+ (input, "local %U port %u", unformat_ip46_address, &local_addr,
+ IP46_TYPE_ANY, &sport));
+ else
+ if (unformat
+ (input, "remote %U port %u", unformat_ip46_address, &remote_addr,
+ IP46_TYPE_ANY, &dport));
+ else if (unformat (input, "intfc %d", &sw_if));
+ else
+ {
+ break;
+ }
+ }
+
+ /* Check for presence of both addresses */
+ if (ip46_address_is_zero (&remote_addr)
+ || ip46_address_is_zero (&local_addr) || sport == 0 || dport == 0)
+ {
+ clib_warning
+ ("Incomplete UDP face. Please specify local and remote address and port");
+ return (1);
+ }
+ /* Construct the API message */
+ M (HICN_API_FACE_ADD, mp);
+ mp->type = UDP_FACE;
+ ip_address_encode (&local_addr, IP46_TYPE_ANY, &mp->face.udp.local_addr);
+ ip_address_encode (&remote_addr, IP46_TYPE_ANY, &mp->face.udp.remote_addr);
+ mp->face.udp.lport = clib_host_to_net_u16 (sport);
+ mp->face.udp.rport = clib_host_to_net_u16 (dport);
+ mp->face.udp.swif = clib_host_to_net_u32 (sw_if);
+
+ /* send it... */
+ S (mp);
+
+ /* Wait for a reply... */
+ W (ret);
+
+ return ret;
+}
+
+static void
+ vl_api_hicn_api_face_add_reply_t_handler
+ (vl_api_hicn_api_face_add_reply_t * rmp)
+{
+ vat_main_t *vam = hicn_test_main.vat_main;
+ i32 retval = ntohl (rmp->retval);
+
+ if (vam->async_mode)
+ {
+ vam->async_errors += (retval < 0);
+ return;
+ }
+ vam->retval = retval;
+ vam->result_ready = 1;
+
+ if (vam->retval < 0)
+ {
+ //vpp_api_test infra will also print out string form of error
+ fformat (vam->ofp, " (API call error: %d)\n", vam->retval);
+ return;
+ }
+ fformat (vam->ofp, "New Face ID: %d\n", ntohl (rmp->faceid));
+}
+
+static int
api_hicn_api_face_ip_del (vat_main_t * vam)
{
unformat_input_t *input = vam->input;
@@ -499,11 +605,48 @@ api_hicn_api_face_ip_del (vat_main_t * vam)
}
static int
+api_hicn_api_face_del (vat_main_t * vam)
+{
+ unformat_input_t *input = vam->input;
+ vl_api_hicn_api_face_del_t *mp;
+ u32 faceid = 0, ret;
+
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (input, "face %d", &faceid))
+ {;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ //Check for presence of face ID
+ if (faceid == ~0)
+ {
+ clib_warning ("Please specify face ID");
+ return 1;
+ }
+ //Construct the API message
+ M (HICN_API_FACE_DEL, mp);
+ mp->faceid = clib_host_to_net_u32 (faceid);
+
+ //send it...
+ S (mp);
+
+ //Wait for a reply...
+ W (ret);
+
+ return ret;
+}
+
+static int
api_hicn_api_face_ip_params_get (vat_main_t * vam)
{
unformat_input_t *input = vam->input;
vl_api_hicn_api_face_ip_params_get_t *mp;
- u32 faceid = 0, ret;
+ u32 faceid = HICN_FACE_NULL, ret;
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
{
@@ -517,7 +660,7 @@ api_hicn_api_face_ip_params_get (vat_main_t * vam)
}
//Check for presence of face ID
- if (faceid == 0)
+ if (faceid == HICN_FACE_NULL)
{
clib_warning ("Please specify face ID");
return 1;
@@ -560,8 +703,8 @@ static void
return;
}
vec_reset_length (sbuf);
- ip_address_decode(&rmp->local_addr, &local_addr);
- ip_address_decode(&rmp->remote_addr, &remote_addr);
+ ip_address_decode (&rmp->local_addr, &local_addr);
+ ip_address_decode (&rmp->remote_addr, &remote_addr);
sbuf =
format (0, "local_addr %U remote_addr %U", format_ip46_address,
&local_addr, 0 /*IP46_ANY_TYPE */ , format_ip46_address,
@@ -569,11 +712,173 @@ static void
fformat (vam->ofp, "%s swif %d flags %d\n",
sbuf,
- clib_net_to_host_u16 (rmp->swif),
+ clib_net_to_host_u32 (rmp->swif),
clib_net_to_host_i32 (rmp->flags));
}
-/* memif-dump API */
+static void format_ip_face (vl_api_hicn_face_ip_t * rmp)
+{
+ vat_main_t *vam = hicn_test_main.vat_main;
+ u8 *sbuf = 0;
+ ip46_address_t remote_addr;
+ ip46_address_t local_addr;
+
+ vec_reset_length (sbuf);
+ ip_address_decode (&rmp->local_addr, &local_addr);
+ ip_address_decode (&rmp->remote_addr, &remote_addr);
+ sbuf =
+ format (0, "local_addr %U remote_addr %U", format_ip46_address,
+ &local_addr, 0 /*IP46_ANY_TYPE */ , format_ip46_address,
+ &remote_addr, 0 /*IP46_ANY_TYPE */ );
+
+ fformat (vam->ofp, "%s swif %d flags %d name %s\n",
+ sbuf,
+ clib_net_to_host_u32 (rmp->swif),
+ clib_net_to_host_i32 (rmp->flags), rmp->if_name);
+}
+
+static void format_udp_face (vl_api_hicn_face_udp_t * rmp)
+{
+ vat_main_t *vam = hicn_test_main.vat_main;
+ u8 *sbuf = 0;
+ ip46_address_t remote_addr;
+ ip46_address_t local_addr;
+
+ vec_reset_length (sbuf);
+ ip_address_decode (&rmp->local_addr, &local_addr);
+ ip_address_decode (&rmp->remote_addr, &remote_addr);
+ u16 lport = clib_net_to_host_u16 (rmp->lport);
+ u16 rport = clib_net_to_host_u16 (rmp->rport);;
+ sbuf =
+ format (0, "local_addr %U port %u remote_addr %U port %u",
+ format_ip46_address, &local_addr, 0 /*IP46_ANY_TYPE */ , lport,
+ format_ip46_address,
+ &remote_addr, 0 /*IP46_ANY_TYPE */ , rport);
+
+ fformat (vam->ofp, "%s swif %d flags %d name %s\n",
+ sbuf,
+ clib_net_to_host_u16 (rmp->swif),
+ clib_net_to_host_i32 (rmp->flags), rmp->if_name);
+}
+
+static int
+api_hicn_api_faces_dump (vat_main_t * vam)
+{
+ hicn_test_main_t *hm = &hicn_test_main;
+ vl_api_hicn_api_faces_dump_t *mp;
+ vl_api_control_ping_t *mp_ping;
+ int ret;
+
+ if (vam->json_output)
+ {
+ clib_warning ("JSON output not supported for faces_dump");
+ return -99;
+ }
+
+ M (HICN_API_FACES_DUMP, mp);
+ S (mp);
+
+ /* Use a control ping for synchronization */
+ mp_ping = vl_msg_api_alloc_as_if_client (sizeof (*mp_ping));
+ mp_ping->_vl_msg_id = htons (hm->ping_id);
+ mp_ping->client_index = vam->my_client_index;
+
+ fformat (vam->ofp, "Sending ping id=%d\n", hm->ping_id);
+
+ vam->result_ready = 0;
+ S (mp_ping);
+
+ W (ret);
+ return ret;
+}
+
+static void
+ vl_api_hicn_api_faces_details_t_handler
+ (vl_api_hicn_api_faces_details_t * mp)
+{
+ if (mp->type == IP_FACE)
+ {
+ format_ip_face (&(mp->face.ip));
+ }
+ else
+ {
+ format_udp_face (&(mp->face.udp));
+ }
+}
+
+static int
+api_hicn_api_face_get (vat_main_t * vam)
+{
+ unformat_input_t *input = vam->input;
+ vl_api_hicn_api_face_get_t *mp;
+ u32 faceid = HICN_FACE_NULL, ret;
+
+ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (input, "face %d", &faceid))
+ {;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ //Check for presence of face ID
+ if (faceid == HICN_FACE_NULL)
+ {
+ clib_warning ("Please specify face ID");
+ return 1;
+ }
+ //Construct the API message
+ M (HICN_API_FACE_GET, mp);
+ mp->faceid = clib_host_to_net_u32 (faceid);
+
+ //send it...
+ S (mp);
+
+ //Wait for a reply...
+ W (ret);
+
+ return ret;
+}
+
+
+static void
+ vl_api_hicn_api_face_get_reply_t_handler
+ (vl_api_hicn_api_face_get_reply_t * rmp)
+{
+
+ vat_main_t *vam = hicn_test_main.vat_main;
+ i32 retval = ntohl (rmp->retval);
+
+ if (vam->async_mode)
+ {
+ vam->async_errors += (retval < 0);
+ return;
+ }
+ vam->retval = retval;
+ vam->result_ready = 1;
+
+ if (vam->retval < 0)
+ {
+ //vpp_api_test infra will also print out string form of error
+ fformat (vam->ofp, " (API call error: %d)\n", vam->retval);
+ return;
+ }
+
+ if (rmp->type == IP_FACE)
+ {
+ format_ip_face (&(rmp->face.ip));
+ }
+ else
+ {
+ format_udp_face (&(rmp->face.udp));
+ }
+}
+
+
+
static int
api_hicn_api_face_stats_dump (vat_main_t * vam)
{
@@ -632,7 +937,6 @@ static void
clib_host_to_net_u64 (mp->dtx_bytes));
}
-
static int
api_hicn_api_route_get (vat_main_t * vam)
{
@@ -655,14 +959,15 @@ api_hicn_api_route_get (vat_main_t * vam)
}
/* Check parse */
- if (((prefix.fp_addr.as_u64[0] == 0) && (prefix.fp_addr.as_u64[1] == 0)) || (prefix.fp_len == 0))
+ if (((prefix.fp_addr.as_u64[0] == 0) && (prefix.fp_addr.as_u64[1] == 0))
+ || (prefix.fp_len == 0))
{
clib_warning ("Please specify a valid prefix...");
return 1;
}
//Construct the API message
M (HICN_API_ROUTE_GET, mp);
- ip_prefix_encode(&prefix, &mp->prefix);
+ ip_prefix_encode (&prefix, &mp->prefix);
//send it...
S (mp);
@@ -764,7 +1069,7 @@ static void
u8 *sbuf = 0;
vec_reset_length (sbuf);
- ip_prefix_decode(&mp->prefix, &prefix);
+ ip_prefix_decode (&mp->prefix, &prefix);
sbuf =
format (sbuf, "Prefix: %U/%u\n", format_ip46_address, &prefix.fp_addr, 0,
prefix.fp_len);
@@ -807,15 +1112,15 @@ api_hicn_api_route_nhops_add (vat_main_t * vam)
}
/* Check parse */
- if (((prefix.fp_addr.as_u64[0] == 0) && (prefix.fp_addr.as_u64[1] == 0)) || (prefix.fp_len == 0)
- || (faceid == 0))
+ if (((prefix.fp_addr.as_u64[0] == 0) && (prefix.fp_addr.as_u64[1] == 0))
+ || (prefix.fp_len == 0) || (faceid == 0))
{
clib_warning ("Please specify prefix and faceid...");
return 1;
}
/* Construct the API message */
M (HICN_API_ROUTE_NHOPS_ADD, mp);
- ip_prefix_encode(&prefix, &mp->prefix);
+ ip_prefix_encode (&prefix, &mp->prefix);
mp->face_ids[0] = clib_host_to_net_u32 (faceid);
mp->n_faces = 1;
@@ -851,14 +1156,15 @@ api_hicn_api_route_del (vat_main_t * vam)
}
/* Check parse */
- if (((prefix.fp_addr.as_u64[0] == 0) && (prefix.fp_addr.as_u64[1] == 0)) || (prefix.fp_len == 0))
+ if (((prefix.fp_addr.as_u64[0] == 0) && (prefix.fp_addr.as_u64[1] == 0))
+ || (prefix.fp_len == 0))
{
clib_warning ("Please specify prefix...");
return 1;
}
/* Construct the API message */
M (HICN_API_ROUTE_DEL, mp);
- ip_prefix_encode(&prefix, &mp->prefix);
+ ip_prefix_encode (&prefix, &mp->prefix);
/* send it... */
S (mp);
@@ -895,15 +1201,15 @@ api_hicn_api_route_nhop_del (vat_main_t * vam)
}
/* Check parse */
- if (((prefix.fp_addr.as_u64[0] == 0) && (prefix.fp_addr.as_u64[1] == 0)) || (prefix.fp_len == 0)
- || (faceid == HICN_FACE_NULL))
+ if (((prefix.fp_addr.as_u64[0] == 0) && (prefix.fp_addr.as_u64[1] == 0))
+ || (prefix.fp_len == 0) || (faceid == HICN_FACE_NULL))
{
clib_warning ("Please specify prefix and faceid...");
return 1;
}
/* Construct the API message */
M (HICN_API_ROUTE_NHOP_DEL, mp);
- ip_prefix_encode(&prefix, &mp->prefix);
+ ip_prefix_encode (&prefix, &mp->prefix);
mp->faceid = clib_host_to_net_u32 (faceid);
@@ -1059,14 +1365,15 @@ api_hicn_api_register_prod_app (vat_main_t * vam)
}
/* Check parse */
- if (((prefix.fp_addr.as_u64[0] == 0) && (prefix.fp_addr.as_u64[1] == 0)) || (prefix.fp_len == 0))
+ if (((prefix.fp_addr.as_u64[0] == 0) && (prefix.fp_addr.as_u64[1] == 0))
+ || (prefix.fp_len == 0))
{
clib_warning ("Please specify prefix...");
return 1;
}
/* Construct the API message */
M (HICN_API_REGISTER_PROD_APP, mp);
- ip_prefix_encode(&prefix, &mp->prefix);
+ ip_prefix_encode (&prefix, &mp->prefix);
mp->swif = clib_host_to_net_u32 (swif);
@@ -1143,14 +1450,15 @@ static void
}
ip46_address_t src_addr4 = ip46_address_initializer;
ip46_address_t src_addr6 = ip46_address_initializer;
- ip_address_decode(&mp->src_addr4, &src_addr4);
- ip_address_decode(&mp->src_addr6, &src_addr6);
+ ip_address_decode (&mp->src_addr4, &src_addr4);
+ ip_address_decode (&mp->src_addr6, &src_addr6);
fformat (vam->ofp,
"ip4 address %U\n"
"ip6 address :%U\n"
"appif id :%d\n",
- format_ip46_address, IP46_TYPE_ANY, &src_addr4, format_ip46_address, IP46_TYPE_ANY, &src_addr6);
+ format_ip46_address, IP46_TYPE_ANY, &src_addr4,
+ format_ip46_address, IP46_TYPE_ANY, &src_addr6);
}
/*
@@ -1164,6 +1472,10 @@ _(hicn_api_node_params_get, "") \
_(hicn_api_node_stats_get, "") \
_(hicn_api_face_ip_del, "face <faceID>") \
_(hicn_api_face_ip_add, "local <address> remote <address> intfc <swif>")\
+_(hicn_api_face_udp_add, "local <address> port <port> remote <address> port <port> intfc <swif>") \
+_(hicn_api_face_del, "face <faceID>") \
+_(hicn_api_faces_dump, "") \
+_(hicn_api_face_get, "face <faceID>") \
_(hicn_api_face_stats_dump, "") \
_(hicn_api_route_nhops_add, "add prefix <IP4/IP6>/<subnet> face <faceID> weight <weight>") \
_(hicn_api_face_ip_params_get, "face <faceID>") \
diff --git a/lib/includes/hicn/util/array.h b/lib/includes/hicn/util/array.h
index ab8852ed8..56cfcad8b 100644
--- a/lib/includes/hicn/util/array.h
+++ b/lib/includes/hicn/util/array.h
@@ -167,9 +167,10 @@ NAME ## _get(const NAME ## _t * array, const T search, T * element)
{ \
assert(element); \
for (unsigned i = 0; i < array->size; i++) \
- if (CMP(search, array->elements[i]) == 0) \
+ if (CMP(search, array->elements[i]) == 0) { \
*element = array->elements[i]; \
return 0; \
+ } \
/* Not found */ \
*element = NULL; \
return 0; \
diff --git a/lib/includes/hicn/util/set.h b/lib/includes/hicn/util/set.h
index c1f43918b..c7dd7bf09 100644
--- a/lib/includes/hicn/util/set.h
+++ b/lib/includes/hicn/util/set.h
@@ -138,10 +138,12 @@ NAME ## _free(NAME ## _t * set) \
int \
NAME ## _add(NAME ## _t * set, const T element) \
{ \
+ T * found = tfind(element, &set->root, (cmp_t)CMP); \
void * ptr = tsearch(element, &set->root, (cmp_t)CMP); \
if (!ptr) \
return -1; \
- set->size++; \
+ if (!found) \
+ set->size++; \
return 0; \
} \
\
@@ -214,7 +216,7 @@ int \
NAME ## _get_array(const NAME ## _t * set, T ** element) \
{ \
if (!element) \
- goto END; \
+ goto END; \
*element = malloc(set->size * sizeof(T)); \
if (!*element) \
return -1; \