summaryrefslogtreecommitdiff
path: root/src/irmd
diff options
context:
space:
mode:
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,