aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJordan Augé <jordan.auge+fdio@cisco.com>2019-11-17 00:07:12 +0100
committerJordan Augé <jordan.auge+fdio@cisco.com>2019-11-17 11:03:31 +0100
commit2ada8954ecd3601d115a22696c4c3ab90858cec3 (patch)
tree6db983388333e8776eecaf9c07c5b7bd6f2f10be
parent2dcc25795fab0100ce33852f08d77a5fd90d8f14 (diff)
[HICN-379] Add face priority support in face manager
Change-Id: If4f75d44fc66414a4a70135de7827f5082b97112 Signed-off-by: Jordan Augé <jordan.auge+fdio@cisco.com>
-rw-r--r--ctrl/facemgr/includes/hicn/facemgr/facelet.h15
-rw-r--r--ctrl/facemgr/src/facelet.c48
-rw-r--r--ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c38
-rw-r--r--ctrl/libhicnctrl/examples/create_face.c3
-rw-r--r--ctrl/libhicnctrl/includes/hicn/ctrl/api.h4
-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/src/api.c70
-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
21 files changed, 414 insertions, 14 deletions
diff --git a/ctrl/facemgr/includes/hicn/facemgr/facelet.h b/ctrl/facemgr/includes/hicn/facemgr/facelet.h
index db76ccdb9..a0318b206 100644
--- a/ctrl/facemgr/includes/hicn/facemgr/facelet.h
+++ b/ctrl/facemgr/includes/hicn/facemgr/facelet.h
@@ -161,6 +161,7 @@ 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) \
@@ -171,7 +172,21 @@ extern const char * facelet_attr_status_str_short[];
_(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) \
+ _(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) \
+ _(facemgr_face_type_t, face_type)
+#endif /* WITH_POLICY */
#define foreach_facelet_event \
_(UNDEFINED) \
diff --git a/ctrl/facemgr/src/facelet.c b/ctrl/facemgr/src/facelet.c
index 761f920c4..929005f57 100644
--- a/ctrl/facemgr/src/facelet.c
+++ b/ctrl/facemgr/src/facelet.c
@@ -124,6 +124,9 @@ 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;
@@ -312,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) {
@@ -809,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 */
@@ -839,6 +861,7 @@ facelet_get_face(const facelet_t * facelet, face_t ** pface)
}
}
face->tags = tags;
+#endif /* WITH_POLICY */
*pface = face;
@@ -1105,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",
@@ -1327,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\"",
diff --git a/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c b/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c
index 53aa95a75..a6cd44fe0 100644
--- a/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c
+++ b/ctrl/facemgr/src/interfaces/hicn_light/hicn_light.c
@@ -294,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
@@ -324,8 +327,6 @@ int hl_on_event(interface_t * interface, const facelet_t * facelet)
facelet_snprintf(buf, MAXSZ_FACELET, facelet);
DEBUG("Create facelet %s", buf);
}
- hc_face.id = 0;
- memset(hc_face.name, 0, sizeof(hc_face.name));
hc_face.face = *face;
rc = hc_face_create(data->s, &hc_face);
if (rc < 0) {
@@ -415,7 +416,7 @@ int hl_on_event(interface_t * interface, const facelet_t * facelet)
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;
@@ -449,6 +450,35 @@ int hl_on_event(interface_t * interface, const facelet_t * facelet)
}
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:
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 d6bb282cb..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)
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/src/api.c b/ctrl/libhicnctrl/src/api.c
index 74a8821e2..14ee69b53 100644
--- a/ctrl/libhicnctrl/src/api.c
+++ b/ctrl/libhicnctrl/src/api.c
@@ -1269,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 */
}
@@ -1546,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,
@@ -1646,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
*----------------------------------------------------------------------------*/
@@ -1924,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 */
};
@@ -1943,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 */
};
@@ -1965,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 */
};
@@ -2010,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 */
},
@@ -2028,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 */
},
@@ -2045,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 */
},
@@ -2450,7 +2508,7 @@ 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 (%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 : "*",
@@ -2459,6 +2517,7 @@ hc_face_snprintf(char * s, size_t size, hc_face_t * face)
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/%s",
@@ -2474,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/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..084be7b17 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(priority_nexthops); k++) {
+ unsigned conn_id = numberSet_GetItem(priority_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;