summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ouroboros/cacep.h6
-rw-r--r--include/ouroboros/irm.h13
-rw-r--r--src/ipcpd/ipcp.c28
-rw-r--r--src/ipcpd/ipcp.h6
-rw-r--r--src/ipcpd/local/main.c4
-rw-r--r--src/ipcpd/normal/ae.h9
-rw-r--r--src/ipcpd/normal/connmgr.c127
-rw-r--r--src/ipcpd/normal/connmgr.h6
-rw-r--r--src/ipcpd/normal/dt.c3
-rw-r--r--src/ipcpd/normal/enroll.c14
-rw-r--r--src/ipcpd/normal/enroll.h3
-rw-r--r--src/ipcpd/normal/main.c5
-rw-r--r--src/ipcpd/shim-eth-llc/main.c2
-rw-r--r--src/ipcpd/shim-udp/main.c4
-rw-r--r--src/irmd/ipcp.c61
-rw-r--r--src/irmd/ipcp.h8
-rw-r--r--src/irmd/main.c82
-rw-r--r--src/lib/ipcpd_messages.proto7
-rw-r--r--src/lib/irm.c66
-rw-r--r--src/lib/irmd_messages.proto31
-rw-r--r--src/tools/irm/CMakeLists.txt2
-rw-r--r--src/tools/irm/irm_ipcp.c18
-rw-r--r--src/tools/irm/irm_ipcp_connect.c94
-rw-r--r--src/tools/irm/irm_ipcp_disconnect.c94
-rw-r--r--src/tools/irm/irm_ops.h6
25 files changed, 635 insertions, 64 deletions
diff --git a/include/ouroboros/cacep.h b/include/ouroboros/cacep.h
index d2b0de9a..4b557b46 100644
--- a/include/ouroboros/cacep.h
+++ b/include/ouroboros/cacep.h
@@ -29,9 +29,11 @@
#include <stdint.h>
#include <sys/types.h>
+#define CACEP_BUF_STRLEN 64
+
struct conn_info {
- char ae_name[64];
- char protocol[64];
+ char ae_name[CACEP_BUF_STRLEN + 1];
+ char protocol[CACEP_BUF_STRLEN + 1];
uint32_t pref_version;
enum proto_concrete_syntax pref_syntax;
struct proto_field fixed_conc_syntax[PROTO_MAX_FIELDS];
diff --git a/include/ouroboros/irm.h b/include/ouroboros/irm.h
index 5ad8f754..dc723fc0 100644
--- a/include/ouroboros/irm.h
+++ b/include/ouroboros/irm.h
@@ -28,8 +28,11 @@
#include <sys/types.h>
-/* Name binding options */
+/* Normal IPCP components. */
+#define DT_AE "Data Transfer"
+#define MGMT_AE "Management"
+/* Name binding options. */
#define BIND_AP_AUTO 0x01
#define BIND_AP_UNIQUE 0x02
@@ -50,6 +53,14 @@ int irm_enroll_ipcp(pid_t api,
int irm_bootstrap_ipcp(pid_t api,
const struct ipcp_config * conf);
+int irm_connect_ipcp(pid_t api,
+ const char * component,
+ const char * dst);
+
+int irm_disconnect_ipcp(pid_t api,
+ const char * component,
+ const char * dst);
+
int irm_bind_ap(const char * ap,
const char * name,
uint16_t opts,
diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c
index d4b3a7fc..41ea4784 100644
--- a/src/ipcpd/ipcp.c
+++ b/src/ipcpd/ipcp.c
@@ -301,6 +301,32 @@ static void * mainloop(void * o)
dif_info.dif_name = info.dif_name;
}
break;
+ case IPCP_MSG_CODE__IPCP_CONNECT:
+ ret_msg.has_result = true;
+
+ if (ipcpi.ops->ipcp_connect == NULL) {
+ log_err("Connect unsupported.");
+ ret_msg.result = -ENOTSUP;
+ break;
+ }
+
+ ret_msg.result =
+ ipcpi.ops->ipcp_connect(msg->dst_name,
+ msg->comp_name);
+ break;
+ case IPCP_MSG_CODE__IPCP_DISCONNECT:
+ ret_msg.has_result = true;
+
+ if (ipcpi.ops->ipcp_disconnect == NULL) {
+ log_err("Disconnect unsupported.");
+ ret_msg.result = -ENOTSUP;
+ break;
+ }
+
+ ret_msg.result =
+ ipcpi.ops->ipcp_disconnect(msg->dst_name,
+ msg->comp_name);
+ break;
case IPCP_MSG_CODE__IPCP_REG:
ret_msg.has_result = true;
@@ -435,6 +461,8 @@ static void * mainloop(void * o)
ipcpi.ops->ipcp_flow_dealloc(fd);
break;
default:
+ ret_msg.has_result = true;
+ ret_msg.result = -1;
log_err("Don't know that message code");
break;
}
diff --git a/src/ipcpd/ipcp.h b/src/ipcpd/ipcp.h
index cd18d198..1b2a0334 100644
--- a/src/ipcpd/ipcp.h
+++ b/src/ipcpd/ipcp.h
@@ -45,6 +45,12 @@ struct ipcp_ops {
int (* ipcp_enroll)(const char * dst,
struct dif_info * info);
+ int (* ipcp_connect)(const char * dst,
+ const char * component);
+
+ int (* ipcp_disconnect)(const char * dst,
+ const char * component);
+
int (* ipcp_reg)(const uint8_t * hash);
int (* ipcp_unreg)(const uint8_t * hash);
diff --git a/src/ipcpd/local/main.c b/src/ipcpd/local/main.c
index 37d23fc3..c6f88d78 100644
--- a/src/ipcpd/local/main.c
+++ b/src/ipcpd/local/main.c
@@ -323,7 +323,9 @@ static int ipcp_local_flow_dealloc(int fd)
static struct ipcp_ops local_ops = {
.ipcp_bootstrap = ipcp_local_bootstrap,
- .ipcp_enroll = NULL, /* shim */
+ .ipcp_enroll = NULL,
+ .ipcp_connect = NULL,
+ .ipcp_disconnect = NULL,
.ipcp_reg = ipcp_local_reg,
.ipcp_unreg = ipcp_local_unreg,
.ipcp_query = ipcp_local_query,
diff --git a/src/ipcpd/normal/ae.h b/src/ipcpd/normal/ae.h
index 4534cefa..3d3bdc27 100644
--- a/src/ipcpd/normal/ae.h
+++ b/src/ipcpd/normal/ae.h
@@ -27,6 +27,8 @@
#include "dt.h"
+#define DST_MAX_STRLEN 64
+
enum ae_id {
AEID_DT = 0,
AEID_ENROLL,
@@ -36,9 +38,10 @@ enum ae_id {
struct conn {
struct conn_info conn_info;
- struct flow_info {
- int fd;
- qosspec_t qs;
+ struct {
+ char dst[DST_MAX_STRLEN + 1];
+ int fd;
+ qosspec_t qs;
} flow_info;
};
diff --git a/src/ipcpd/normal/connmgr.c b/src/ipcpd/normal/connmgr.c
index b6e5e31a..11f83247 100644
--- a/src/ipcpd/normal/connmgr.c
+++ b/src/ipcpd/normal/connmgr.c
@@ -48,7 +48,7 @@ enum connmgr_state {
CONNMGR_RUNNING
};
-struct ae_conn {
+struct conn_el {
struct list_head next;
struct conn conn;
};
@@ -58,15 +58,17 @@ struct ae {
struct conn_info info;
struct list_head conns;
+ struct list_head pending;
+
pthread_cond_t cond;
pthread_mutex_t lock;
};
struct {
- struct ae aes[AEID_MAX];
- enum connmgr_state state;
+ struct ae aes[AEID_MAX];
+ enum connmgr_state state;
- pthread_t acceptor;
+ pthread_t acceptor;
} connmgr;
static int get_id_by_name(const char * name)
@@ -85,23 +87,21 @@ static int add_ae_conn(enum ae_id id,
qosspec_t qs,
struct conn_info * rcv_info)
{
- struct ae_conn * ae_conn;
+ struct conn_el * el;
- ae_conn = malloc(sizeof(*ae_conn));
- if (ae_conn == NULL) {
+ el = malloc(sizeof(*el));
+ if (el == NULL) {
log_err("Not enough memory.");
return -1;
}
- ae_conn->conn.conn_info = *rcv_info;
- ae_conn->conn.flow_info.fd = fd;
- ae_conn->conn.flow_info.qs = qs;
-
- list_head_init(&ae_conn->next);
+ el->conn.conn_info = *rcv_info;
+ el->conn.flow_info.fd = fd;
+ el->conn.flow_info.qs = qs;
pthread_mutex_lock(&connmgr.aes[id].lock);
- list_add(&ae_conn->next, &connmgr.aes[id].conns);
+ list_add(&el->next, &connmgr.aes[id].pending);
pthread_cond_signal(&connmgr.aes[id].cond);
pthread_mutex_unlock(&connmgr.aes[id].lock);
@@ -217,6 +217,7 @@ int connmgr_ae_init(enum ae_id id,
}
list_head_init(&ae->conns);
+ list_head_init(&ae->pending);
memcpy(&connmgr.aes[id].info, info, sizeof(connmgr.aes[id].info));
@@ -241,7 +242,13 @@ void connmgr_ae_fini(enum ae_id id)
pthread_mutex_lock(&ae->lock);
list_for_each_safe(p, h, &ae->conns) {
- struct ae_conn * e = list_entry(p, struct ae_conn, next);
+ struct conn_el * e = list_entry(p, struct conn_el, next);
+ list_del(&e->next);
+ free(e);
+ }
+
+ list_for_each_safe(p, h, &ae->pending) {
+ struct conn_el * e = list_entry(p, struct conn_el, next);
list_del(&e->next);
free(e);
}
@@ -256,6 +263,84 @@ void connmgr_ae_fini(enum ae_id id)
connmgr.aes[id].nbs = NULL;
}
+int connmgr_ipcp_connect(const char * dst,
+ const char * component)
+{
+ struct conn_el * ce;
+ int id;
+
+ assert(dst);
+ assert(component);
+
+ ce = malloc(sizeof(*ce));
+ if (ce == NULL) {
+ log_dbg("Out of memory.");
+ return -1;
+ }
+
+ id = get_id_by_name(component);
+ if (id < 0) {
+ log_dbg("No such component: %s", component);
+ free(ce);
+ return -1;
+ }
+
+ /* FIXME: get the correct qos for the component. */
+ if (connmgr_alloc(id, dst, NULL, &ce->conn)) {
+ free(ce);
+ return -1;
+ }
+
+ if (strlen(dst) > DST_MAX_STRLEN) {
+ log_warn("Truncating dst length for connection.");
+ memcpy(ce->conn.flow_info.dst, dst, DST_MAX_STRLEN);
+ ce->conn.flow_info.dst[DST_MAX_STRLEN] = '\0';
+ } else {
+ strcpy(ce->conn.flow_info.dst, dst);
+ }
+
+ pthread_mutex_lock(&connmgr.aes[id].lock);
+
+ list_add(&ce->next, &connmgr.aes[id].conns);
+
+ pthread_mutex_unlock(&connmgr.aes[id].lock);
+
+ return 0;
+}
+
+int connmgr_ipcp_disconnect(const char * dst,
+ const char * component)
+{
+ struct list_head * p;
+ struct list_head * h;
+ int id;
+
+ assert(dst);
+ assert(component);
+
+ id = get_id_by_name(component);
+ if (id < 0)
+ return -1;
+
+ pthread_mutex_lock(&connmgr.aes[id].lock);
+
+ list_for_each_safe(p,h, &connmgr.aes[id].conns) {
+ struct conn_el * el = list_entry(p, struct conn_el, next);
+ if (strcmp(el->conn.flow_info.dst, dst) == 0) {
+ int ret;
+ pthread_mutex_unlock(&connmgr.aes[id].lock);
+ list_del(&el->next);
+ ret = connmgr_dealloc(id, &el->conn);
+ free(el);
+ return ret;
+ }
+ }
+
+ pthread_mutex_unlock(&connmgr.aes[id].lock);
+
+ return 0;
+}
+
int connmgr_alloc(enum ae_id id,
const char * dst,
qosspec_t * qs,
@@ -329,7 +414,7 @@ int connmgr_dealloc(enum ae_id id,
int connmgr_wait(enum ae_id id,
struct conn * conn)
{
- struct ae_conn * ae_conn;
+ struct conn_el * el;
struct ae * ae;
assert(id >= 0 && id < AEID_MAX);
@@ -342,21 +427,21 @@ int connmgr_wait(enum ae_id id,
pthread_cleanup_push((void(*)(void *))pthread_mutex_unlock,
(void *) &ae->lock);
- while (list_is_empty(&ae->conns))
+ while (list_is_empty(&ae->pending))
pthread_cond_wait(&ae->cond, &ae->lock);
pthread_cleanup_pop(false);
- ae_conn = list_first_entry((&ae->conns), struct ae_conn, next);
- if (ae_conn == NULL) {
+ el = list_first_entry((&ae->pending), struct conn_el, next);
+ if (el == NULL) {
pthread_mutex_unlock(&ae->lock);
return -1;
}
- *conn = ae_conn->conn;
+ *conn = el->conn;
- list_del(&ae_conn->next);
- free(ae_conn);
+ list_del(&el->next);
+ free(el);
pthread_mutex_unlock(&ae->lock);
diff --git a/src/ipcpd/normal/connmgr.h b/src/ipcpd/normal/connmgr.h
index 920058da..379877e6 100644
--- a/src/ipcpd/normal/connmgr.h
+++ b/src/ipcpd/normal/connmgr.h
@@ -43,6 +43,12 @@ int connmgr_ae_init(enum ae_id id,
void connmgr_ae_fini(enum ae_id id);
+int connmgr_ipcp_connect(const char * dst,
+ const char * component);
+
+int connmgr_ipcp_disconnect(const char * dst,
+ const char * component);
+
int connmgr_alloc(enum ae_id id,
const char * dst,
qosspec_t * qs,
diff --git a/src/ipcpd/normal/dt.c b/src/ipcpd/normal/dt.c
index 19c2d3a6..aa089852 100644
--- a/src/ipcpd/normal/dt.c
+++ b/src/ipcpd/normal/dt.c
@@ -67,7 +67,6 @@ struct {
pthread_rwlock_t lock;
struct nbs * nbs;
- struct ae * ae;
struct nb_notifier nb_notifier;
@@ -163,6 +162,8 @@ static void * dt_conn_handle(void * o)
log_dbg("Got new connection.");
+ /* NOTE: connection acceptance policy could be here. */
+
nbs_add(dt.nbs, conn);
}
diff --git a/src/ipcpd/normal/enroll.c b/src/ipcpd/normal/enroll.c
index 2f7dd9bc..7f93ed3a 100644
--- a/src/ipcpd/normal/enroll.c
+++ b/src/ipcpd/normal/enroll.c
@@ -259,14 +259,17 @@ static void * enroll_handle(void * o)
continue;
}
- if (msg->code != ENROLL_CODE__ENROLL_DONE) {
+ if (msg->code != ENROLL_CODE__ENROLL_DONE || !msg->has_result) {
log_err("Wrong message type.");
enroll_msg__free_unpacked(msg, NULL);
connmgr_dealloc(AEID_ENROLL, &conn);
continue;
}
- log_dbg("Neighbor enrollment successful.");
+ if (msg->result == 0)
+ log_dbg("Neighbor enrollment successful.");
+ else
+ log_dbg("Neigbor reported failed enrollment.");
connmgr_dealloc(AEID_ENROLL, &conn);
}
@@ -287,13 +290,16 @@ int enroll_boot(struct conn * conn,
return 0;
}
-int enroll_done(struct conn * conn)
+int enroll_done(struct conn * conn,
+ int result)
{
enroll_msg_t msg = ENROLL_MSG__INIT;
uint8_t buf[ENROLL_BUF_LEN];
ssize_t len;
- msg.code = ENROLL_CODE__ENROLL_DONE;
+ msg.code = ENROLL_CODE__ENROLL_DONE;
+ msg.has_result = true;
+ msg.result = result;
len = enroll_msg__get_packed_size(&msg);
if (len < 0) {
diff --git a/src/ipcpd/normal/enroll.h b/src/ipcpd/normal/enroll.h
index 67c9912d..3b277e44 100644
--- a/src/ipcpd/normal/enroll.h
+++ b/src/ipcpd/normal/enroll.h
@@ -40,7 +40,8 @@ void enroll_bootstrap(const struct ipcp_config * conf);
int enroll_boot(struct conn * conn,
const char * dst);
-int enroll_done(struct conn * conn);
+int enroll_done(struct conn * conn,
+ int result);
struct ipcp_config * enroll_get_conf(void);
diff --git a/src/ipcpd/normal/main.c b/src/ipcpd/normal/main.c
index d9fbc2dd..bef04b7a 100644
--- a/src/ipcpd/normal/main.c
+++ b/src/ipcpd/normal/main.c
@@ -263,11 +263,12 @@ static int normal_ipcp_enroll(const char * dst,
}
if (enroll_components(dt_conn.conn_info.addr)) {
+ enroll_done(&er_conn, -1);
log_err("Failed to enroll components.");
goto fail_enroll_comp;
}
- if (enroll_done(&er_conn))
+ if (enroll_done(&er_conn, 0))
log_warn("Failed to confirm enrollment with peer.");
if (connmgr_dealloc(AEID_DT, &dt_conn))
@@ -346,6 +347,8 @@ static int normal_ipcp_query(const uint8_t * dst)
static struct ipcp_ops normal_ops = {
.ipcp_bootstrap = normal_ipcp_bootstrap,
.ipcp_enroll = normal_ipcp_enroll,
+ .ipcp_connect = connmgr_ipcp_connect,
+ .ipcp_disconnect = connmgr_ipcp_disconnect,
.ipcp_reg = dir_reg,
.ipcp_unreg = dir_unreg,
.ipcp_query = normal_ipcp_query,
diff --git a/src/ipcpd/shim-eth-llc/main.c b/src/ipcpd/shim-eth-llc/main.c
index bcf5abe2..3d186d7a 100644
--- a/src/ipcpd/shim-eth-llc/main.c
+++ b/src/ipcpd/shim-eth-llc/main.c
@@ -1216,6 +1216,8 @@ static int eth_llc_ipcp_flow_dealloc(int fd)
static struct ipcp_ops eth_llc_ops = {
.ipcp_bootstrap = eth_llc_ipcp_bootstrap,
.ipcp_enroll = NULL,
+ .ipcp_connect = NULL,
+ .ipcp_disconnect = NULL,
.ipcp_reg = eth_llc_ipcp_reg,
.ipcp_unreg = eth_llc_ipcp_unreg,
.ipcp_query = eth_llc_ipcp_query,
diff --git a/src/ipcpd/shim-udp/main.c b/src/ipcpd/shim-udp/main.c
index 55fe19a6..0bf57741 100644
--- a/src/ipcpd/shim-udp/main.c
+++ b/src/ipcpd/shim-udp/main.c
@@ -1092,7 +1092,9 @@ static int ipcp_udp_flow_dealloc(int fd)
static struct ipcp_ops udp_ops = {
.ipcp_bootstrap = ipcp_udp_bootstrap,
- .ipcp_enroll = NULL, /* shim */
+ .ipcp_enroll = NULL,
+ .ipcp_connect = NULL,
+ .ipcp_disconnect = NULL,
.ipcp_reg = ipcp_udp_reg,
.ipcp_unreg = ipcp_udp_unreg,
.ipcp_query = ipcp_udp_query,
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,
diff --git a/src/lib/ipcpd_messages.proto b/src/lib/ipcpd_messages.proto
index 2e6c0497..691b76ad 100644
--- a/src/lib/ipcpd_messages.proto
+++ b/src/lib/ipcpd_messages.proto
@@ -33,7 +33,9 @@ enum ipcp_msg_code {
IPCP_FLOW_ALLOC = 6;
IPCP_FLOW_ALLOC_RESP = 7;
IPCP_FLOW_DEALLOC = 8;
- IPCP_REPLY = 9;
+ IPCP_CONNECT = 9;
+ IPCP_DISCONNECT = 10;
+ IPCP_REPLY = 11;
};
message ipcp_msg {
@@ -47,5 +49,6 @@ message ipcp_msg {
optional int32 api = 8;
optional dif_info_msg dif_info = 9;
optional int32 response = 10;
- optional int32 result = 11;
+ optional string comp_name = 11;
+ optional int32 result = 12;
};
diff --git a/src/lib/irm.c b/src/lib/irm.c
index eec89338..ce17bf18 100644
--- a/src/lib/irm.c
+++ b/src/lib/irm.c
@@ -146,7 +146,65 @@ int irm_bootstrap_ipcp(pid_t api,
if (recv_msg->has_result == false) {
irm_msg__free_unpacked(recv_msg, NULL);
- return -1;
+ return -EIRMD;
+ }
+
+ ret = recv_msg->result;
+ irm_msg__free_unpacked(recv_msg, NULL);
+
+ return ret;
+}
+
+int irm_connect_ipcp(pid_t api,
+ const char * dst,
+ const char * component)
+{
+ irm_msg_t msg = IRM_MSG__INIT;
+ irm_msg_t * recv_msg = NULL;
+ int ret;
+
+ msg.code = IRM_MSG_CODE__IRM_CONNECT_IPCP;
+ msg.dst_name = (char *) dst;
+ msg.comp_name = (char *) component;
+ msg.has_api = true;
+ msg.api = api;
+
+ recv_msg = send_recv_irm_msg(&msg);
+ if (recv_msg == NULL)
+ return -EIRMD;
+
+ if (recv_msg->has_result == false) {
+ irm_msg__free_unpacked(recv_msg, NULL);
+ return -EIRMD;
+ }
+
+ ret = recv_msg->result;
+ irm_msg__free_unpacked(recv_msg, NULL);
+
+ return ret;
+}
+
+int irm_disconnect_ipcp(pid_t api,
+ const char * dst,
+ const char * component)
+{
+ irm_msg_t msg = IRM_MSG__INIT;
+ irm_msg_t * recv_msg = NULL;
+ int ret;
+
+ msg.code = IRM_MSG_CODE__IRM_DISCONNECT_IPCP;
+ msg.dst_name = (char *) dst;
+ msg.comp_name = (char *) component;
+ msg.has_api = true;
+ msg.api = api;
+
+ recv_msg = send_recv_irm_msg(&msg);
+ if (recv_msg == NULL)
+ return -EIRMD;
+
+ if (recv_msg->has_result == false) {
+ irm_msg__free_unpacked(recv_msg, NULL);
+ return -EIRMD;
}
ret = recv_msg->result;
@@ -158,15 +216,15 @@ int irm_bootstrap_ipcp(pid_t api,
ssize_t irm_list_ipcps(const char * name,
pid_t ** apis)
{
- irm_msg_t msg = IRM_MSG__INIT;
+ irm_msg_t msg = IRM_MSG__INIT;
irm_msg_t * recv_msg = NULL;
- size_t nr = 0;
+ size_t nr = 0;
size_t i;
if (apis == NULL)
return -EINVAL;
- msg.code = IRM_MSG_CODE__IRM_LIST_IPCPS;
+ msg.code = IRM_MSG_CODE__IRM_LIST_IPCPS;
msg.dst_name = (char *) name;
recv_msg = send_recv_irm_msg(&msg);
diff --git a/src/lib/irmd_messages.proto b/src/lib/irmd_messages.proto
index 117752c8..723f6fb3 100644
--- a/src/lib/irmd_messages.proto
+++ b/src/lib/irmd_messages.proto
@@ -31,19 +31,21 @@ enum irm_msg_code {
IRM_LIST_IPCPS = 4;
IRM_BOOTSTRAP_IPCP = 5;
IRM_ENROLL_IPCP = 6;
- IRM_BIND_AP = 7;
- IRM_UNBIND_AP = 8;
- IRM_API_ANNOUNCE = 9;
- IRM_BIND_API = 10;
- IRM_UNBIND_API = 11;
- IRM_REG = 12;
- IRM_UNREG = 13;
- IRM_FLOW_ALLOC = 14;
- IRM_FLOW_ACCEPT = 15;
- IRM_FLOW_DEALLOC = 16;
- IPCP_FLOW_REQ_ARR = 17;
- IPCP_FLOW_ALLOC_REPLY = 18;
- IRM_REPLY = 19;
+ IRM_CONNECT_IPCP = 7;
+ IRM_DISCONNECT_IPCP = 8;
+ IRM_BIND_AP = 9;
+ IRM_UNBIND_AP = 10;
+ IRM_API_ANNOUNCE = 11;
+ IRM_BIND_API = 12;
+ IRM_UNBIND_API = 13;
+ IRM_REG = 14;
+ IRM_UNREG = 15;
+ IRM_FLOW_ALLOC = 16;
+ IRM_FLOW_ACCEPT = 17;
+ IRM_FLOW_DEALLOC = 18;
+ IPCP_FLOW_REQ_ARR = 19;
+ IPCP_FLOW_ALLOC_REPLY = 20;
+ IRM_REPLY = 21;
};
message irm_msg {
@@ -63,5 +65,6 @@ message irm_msg {
repeated sint32 apis = 14;
optional uint32 timeo_sec = 15;
optional uint32 timeo_nsec = 16;
- optional sint32 result = 17;
+ optional string comp_name = 17;
+ optional sint32 result = 18;
};
diff --git a/src/tools/irm/CMakeLists.txt b/src/tools/irm/CMakeLists.txt
index 300ad982..895bc746 100644
--- a/src/tools/irm/CMakeLists.txt
+++ b/src/tools/irm/CMakeLists.txt
@@ -14,6 +14,8 @@ set(SOURCE_FILES
irm_ipcp_destroy.c
irm_ipcp_bootstrap.c
irm_ipcp_enroll.c
+ irm_ipcp_connect.c
+ irm_ipcp_disconnect.c
irm_unbind_ap.c
irm_unbind_api.c
irm_unbind_ipcp.c
diff --git a/src/tools/irm/irm_ipcp.c b/src/tools/irm/irm_ipcp.c
index 2850ac89..2f7b01c9 100644
--- a/src/tools/irm/irm_ipcp.c
+++ b/src/tools/irm/irm_ipcp.c
@@ -45,17 +45,19 @@ static const struct cmd {
const char * cmd;
int (* func)(int argc, char ** argv);
} cmds[] = {
- { "create", do_create_ipcp },
- { "destroy", do_destroy_ipcp },
- { "bootstrap", do_bootstrap_ipcp },
- { "enroll", do_enroll_ipcp },
- { "help", do_help },
- { NULL, NULL }
+ { "create", do_create_ipcp },
+ { "destroy", do_destroy_ipcp },
+ { "bootstrap", do_bootstrap_ipcp },
+ { "enroll", do_enroll_ipcp },
+ { "connect", do_connect_ipcp },
+ { "disconnect", do_disconnect_ipcp },
+ { "help", do_help },
+ { NULL, NULL }
};
static int do_cmd(const char * argv0,
- int argc,
- char ** argv)
+ int argc,
+ char ** argv)
{
const struct cmd * c;
diff --git a/src/tools/irm/irm_ipcp_connect.c b/src/tools/irm/irm_ipcp_connect.c
new file mode 100644
index 00000000..168c8d17
--- /dev/null
+++ b/src/tools/irm/irm_ipcp_connect.c
@@ -0,0 +1,94 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2017
+ *
+ * Connect components of normal IPC Processes
+ *
+ * Dimitri Staessens <[email protected]>
+ * Sander Vrijders <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., http://www.fsf.org/about/contact/.
+ */
+
+#include <ouroboros/irm.h>
+
+#include "irm_ops.h"
+#include "irm_utils.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define DT "dt"
+#define MGMT "mgmt"
+
+static void usage(void)
+{
+ printf("Usage: irm ipcp connect\n"
+ " name <ipcp name>\n"
+ " comp <COMPONENT>\n"
+ " dst <name of destination IPCP>\n"
+ "where COMPONENT = {" DT " " MGMT "},\n\n");
+}
+
+int do_connect_ipcp(int argc,
+ char ** argv)
+{
+ char * name = NULL;
+ char * dst_name = NULL;
+ char * comp_name = NULL;
+ pid_t * apis = NULL;
+ ssize_t len = 0;
+
+ while (argc > 0) {
+ if (strcmp(*argv, "name") == 0) {
+ name = *(argv + 1);
+ } else if (matches(*argv, "dst") == 0) {
+ dst_name = *(argv + 1);
+ } else if (matches(*argv, "comp") == 0) {
+ comp_name = *(argv + 1);
+ } else {
+ printf("\"%s\" is unknown, try \"irm "
+ "ipcpi connect\".\n", *argv);
+ return -1;
+ }
+
+ argc -= 2;
+ argv += 2;
+ }
+
+ if (name == NULL || dst_name == NULL || comp_name == NULL) {
+ usage();
+ return -1;
+ }
+
+ len = irm_list_ipcps(name, &apis);
+ if (len != 1)
+ return -1;
+
+ if (!strcmp(comp_name, DT))
+ comp_name = DT_AE;
+
+ if (!strcmp(comp_name , MGMT))
+ comp_name = MGMT_AE;
+
+ if (irm_connect_ipcp(apis[0], dst_name, comp_name)) {
+ free(apis);
+ return -1;
+ }
+
+ if (apis != NULL)
+ free(apis);
+
+ return 0;
+}
diff --git a/src/tools/irm/irm_ipcp_disconnect.c b/src/tools/irm/irm_ipcp_disconnect.c
new file mode 100644
index 00000000..8f83f3e8
--- /dev/null
+++ b/src/tools/irm/irm_ipcp_disconnect.c
@@ -0,0 +1,94 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2017
+ *
+ * Connect components of normal IPC Processes
+ *
+ * Dimitri Staessens <[email protected]>
+ * Sander Vrijders <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., http://www.fsf.org/about/contact/.
+ */
+
+#include <ouroboros/irm.h>
+
+#include "irm_ops.h"
+#include "irm_utils.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define DT "dt"
+#define MGMT "mgmt"
+
+static void usage(void)
+{
+ printf("Usage: irm ipcp disconnect\n"
+ " name <ipcp name>\n"
+ " comp <COMPONENT>\n"
+ " dst <name of destination IPCP>\n"
+ "where COMPONENT = {" DT " " MGMT "},\n\n");
+}
+
+int do_disconnect_ipcp(int argc,
+ char ** argv)
+{
+ char * name = NULL;
+ char * dst_name = NULL;
+ char * comp_name = NULL;
+ pid_t * apis = NULL;
+ ssize_t len = 0;
+
+ while (argc > 0) {
+ if (strcmp(*argv, "name") == 0) {
+ name = *(argv + 1);
+ } else if (matches(*argv, "dst") == 0) {
+ dst_name = *(argv + 1);
+ } else if (matches(*argv, "comp") == 0) {
+ comp_name = *(argv + 1);
+ } else {
+ printf("\"%s\" is unknown, try \"irm "
+ "ipcpi connect\".\n", *argv);
+ return -1;
+ }
+
+ argc -= 2;
+ argv += 2;
+ }
+
+ if (name == NULL || dst_name == NULL || comp_name == NULL) {
+ usage();
+ return -1;
+ }
+
+ len = irm_list_ipcps(name, &apis);
+ if (len != 1)
+ return -1;
+
+ if (!strcmp(comp_name, DT))
+ comp_name = DT_AE;
+
+ if (!strcmp(comp_name , MGMT))
+ comp_name = MGMT_AE;
+
+ if (irm_disconnect_ipcp(apis[0], dst_name, comp_name)) {
+ free(apis);
+ return -1;
+ }
+
+ if (apis != NULL)
+ free(apis);
+
+ return 0;
+}
diff --git a/src/tools/irm/irm_ops.h b/src/tools/irm/irm_ops.h
index 749ea13d..a2bc40b4 100644
--- a/src/tools/irm/irm_ops.h
+++ b/src/tools/irm/irm_ops.h
@@ -35,6 +35,12 @@ int do_bootstrap_ipcp(int argc,
int do_enroll_ipcp(int argc,
char ** argv);
+int do_connect_ipcp(int argc,
+ char ** argv);
+
+int do_disconnect_ipcp(int argc,
+ char ** argv);
+
int bind_cmd(int argc,
char ** argv);