diff options
author | dimitri staessens <dimitri.staessens@ugent.be> | 2017-08-28 18:54:22 +0200 |
---|---|---|
committer | dimitri staessens <dimitri.staessens@ugent.be> | 2017-08-28 20:49:34 +0200 |
commit | 9de8dc4948cf7ce239232aae0889c39ffa39ede2 (patch) | |
tree | 396295b2d36f69ee55e5080e556891f11210aed8 /src/irmd | |
parent | 176698e8c2fd7ab8007b8074515d6144e7177d8e (diff) | |
download | ouroboros-9de8dc4948cf7ce239232aae0889c39ffa39ede2.tar.gz ouroboros-9de8dc4948cf7ce239232aae0889c39ffa39ede2.zip |
tools: Add tool to connect IPCP components
This enables user-written tools to instruct IPCPs to establish and
tear down connections (a.k.a. adjacencies) between its internal
components (Management and Data Transfer).
For more info, do "irm ipcp connect" or "irm ipcp disconnect" on the
command line.
This commit exposes a deletion bug in the RIB where FSO's fail to
unpack/parse. This will be fixed when the RIB is deprecated.
Diffstat (limited to 'src/irmd')
-rw-r--r-- | src/irmd/ipcp.c | 61 | ||||
-rw-r--r-- | src/irmd/ipcp.h | 8 | ||||
-rw-r--r-- | src/irmd/main.c | 82 |
3 files changed, 151 insertions, 0 deletions
diff --git a/src/irmd/ipcp.c b/src/irmd/ipcp.c index e1689b91..ed1ad924 100644 --- a/src/irmd/ipcp.c +++ b/src/irmd/ipcp.c @@ -281,6 +281,67 @@ int ipcp_enroll(pid_t api, return 0; } +int ipcp_connect(pid_t api, + const char * dst, + const char * component) +{ + ipcp_msg_t msg = IPCP_MSG__INIT; + ipcp_msg_t * recv_msg = NULL; + int ret = -1; + + msg.code = IPCP_MSG_CODE__IPCP_CONNECT; + msg.dst_name = (char *) dst; + msg.comp_name = (char *) component; + msg.has_api = true; + msg.api = api; + + recv_msg = send_recv_ipcp_msg(api, &msg); + if (recv_msg == NULL) { + log_dbg("bad msg"); + return -EIPCP; + } + + if (recv_msg->has_result == false) { + ipcp_msg__free_unpacked(recv_msg, NULL); + log_dbg("no result."); + return -EIPCP; + } + + ret = recv_msg->result; + ipcp_msg__free_unpacked(recv_msg, NULL); + + return ret; +} + +int ipcp_disconnect(pid_t api, + const char * dst, + const char * component) +{ + ipcp_msg_t msg = IPCP_MSG__INIT; + ipcp_msg_t * recv_msg = NULL; + int ret = -1; + + msg.code = IPCP_MSG_CODE__IPCP_DISCONNECT; + msg.dst_name = (char *) dst; + msg.comp_name = (char *) component; + msg.has_api = true; + msg.api = api; + + recv_msg = send_recv_ipcp_msg(api, &msg); + if (recv_msg == NULL) + return -EIPCP; + + if (recv_msg->has_result == false) { + ipcp_msg__free_unpacked(recv_msg, NULL); + return -EIPCP; + } + + ret = recv_msg->result; + ipcp_msg__free_unpacked(recv_msg, NULL); + + return ret; +} + int ipcp_reg(pid_t api, const uint8_t * hash, size_t len) diff --git a/src/irmd/ipcp.h b/src/irmd/ipcp.h index 67d0476f..9c861cde 100644 --- a/src/irmd/ipcp.h +++ b/src/irmd/ipcp.h @@ -42,6 +42,14 @@ int ipcp_bootstrap(pid_t api, ipcp_config_msg_t * conf, struct dif_info * info); +int ipcp_connect(pid_t api, + const char * dst, + const char * component); + +int ipcp_disconnect(pid_t api, + const char * dst, + const char * component); + int ipcp_reg(pid_t api, const uint8_t * hash, size_t len); diff --git a/src/irmd/main.c b/src/irmd/main.c index e72153ae..cc15e092 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -555,6 +555,76 @@ static int enroll_ipcp(pid_t api, return 0; } +static int connect_ipcp(pid_t api, + const char * dst, + const char * component) +{ + struct ipcp_entry * entry = NULL; + + pthread_rwlock_rdlock(&irmd.reg_lock); + + entry = get_ipcp_entry_by_api(api); + if (entry == NULL) { + pthread_rwlock_unlock(&irmd.reg_lock); + log_err("No such IPCP."); + return -EIPCP; + } + + if (entry->type != IPCP_NORMAL) { + pthread_rwlock_unlock(&irmd.reg_lock); + log_err("Cannot establish connections for this IPCP type."); + return -EIPCP; + } + + pthread_rwlock_unlock(&irmd.reg_lock); + + log_dbg("Connecting %s to %s.", component, dst); + + if (ipcp_connect(api, dst, component)) { + log_err("Could not connect IPCP."); + return -EPERM; + } + + log_info("Established %s connection between IPCP %d and %s.", + component, api, dst); + + return 0; +} + +static int disconnect_ipcp(pid_t api, + const char * dst, + const char * component) +{ + struct ipcp_entry * entry = NULL; + + pthread_rwlock_rdlock(&irmd.reg_lock); + + entry = get_ipcp_entry_by_api(api); + if (entry == NULL) { + pthread_rwlock_unlock(&irmd.reg_lock); + log_err("No such IPCP."); + return -EIPCP; + } + + if (entry->type != IPCP_NORMAL) { + pthread_rwlock_unlock(&irmd.reg_lock); + log_err("Cannot tear down connections for this IPCP type."); + return -EIPCP; + } + + pthread_rwlock_unlock(&irmd.reg_lock); + + if (ipcp_disconnect(api, dst, component)) { + log_err("Could not disconnect IPCP."); + return -EPERM; + } + + log_info("%s connection between IPCP %d and %s torn down.", + component, api, dst); + + return 0; +} + static int bind_ap(char * ap, char * name, uint16_t flags, @@ -1876,6 +1946,18 @@ void * mainloop(void * o) ret_msg.result = enroll_ipcp(msg->api, msg->dif_name[0]); break; + case IRM_MSG_CODE__IRM_CONNECT_IPCP: + ret_msg.has_result = true; + ret_msg.result = connect_ipcp(msg->api, + msg->dst_name, + msg->comp_name); + break; + case IRM_MSG_CODE__IRM_DISCONNECT_IPCP: + ret_msg.has_result = true; + ret_msg.result = disconnect_ipcp(msg->api, + msg->dst_name, + msg->comp_name); + break; case IRM_MSG_CODE__IRM_BIND_AP: ret_msg.has_result = true; ret_msg.result = bind_ap(msg->ap_name, |