summaryrefslogtreecommitdiff
path: root/src/irmd
diff options
context:
space:
mode:
authordimitri staessens <[email protected]>2017-08-28 18:54:22 +0200
committerdimitri staessens <[email protected]>2017-08-28 20:49:34 +0200
commit9de8dc4948cf7ce239232aae0889c39ffa39ede2 (patch)
tree396295b2d36f69ee55e5080e556891f11210aed8 /src/irmd
parent176698e8c2fd7ab8007b8074515d6144e7177d8e (diff)
downloadouroboros-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.c61
-rw-r--r--src/irmd/ipcp.h8
-rw-r--r--src/irmd/main.c82
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,