From 2ada8954ecd3601d115a22696c4c3ab90858cec3 Mon Sep 17 00:00:00 2001 From: Jordan Augé Date: Sun, 17 Nov 2019 00:07:12 +0100 Subject: [HICN-379] Add face priority support in face manager MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: If4f75d44fc66414a4a70135de7827f5082b97112 Signed-off-by: Jordan Augé --- ctrl/facemgr/includes/hicn/facemgr/facelet.h | 15 +++++ ctrl/facemgr/src/facelet.c | 48 +++++++++++++++ .../facemgr/src/interfaces/hicn_light/hicn_light.c | 38 ++++++++++-- ctrl/libhicnctrl/examples/create_face.c | 3 + ctrl/libhicnctrl/includes/hicn/ctrl/api.h | 4 +- ctrl/libhicnctrl/includes/hicn/ctrl/commands.h | 13 ++++ ctrl/libhicnctrl/includes/hicn/ctrl/face.h | 1 + ctrl/libhicnctrl/src/api.c | 70 +++++++++++++++++++++- 8 files changed, 185 insertions(+), 7 deletions(-) (limited to 'ctrl') 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), ¶ms, 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 *----------------------------------------------------------------------------*/ -- cgit 1.2.3-korg