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 | |
| 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')
| -rw-r--r-- | src/ipcpd/ipcp.c | 28 | ||||
| -rw-r--r-- | src/ipcpd/ipcp.h | 6 | ||||
| -rw-r--r-- | src/ipcpd/local/main.c | 4 | ||||
| -rw-r--r-- | src/ipcpd/normal/ae.h | 9 | ||||
| -rw-r--r-- | src/ipcpd/normal/connmgr.c | 127 | ||||
| -rw-r--r-- | src/ipcpd/normal/connmgr.h | 6 | ||||
| -rw-r--r-- | src/ipcpd/normal/dt.c | 3 | ||||
| -rw-r--r-- | src/ipcpd/normal/enroll.c | 14 | ||||
| -rw-r--r-- | src/ipcpd/normal/enroll.h | 3 | ||||
| -rw-r--r-- | src/ipcpd/normal/main.c | 5 | ||||
| -rw-r--r-- | src/ipcpd/shim-eth-llc/main.c | 2 | ||||
| -rw-r--r-- | src/ipcpd/shim-udp/main.c | 4 | ||||
| -rw-r--r-- | src/irmd/ipcp.c | 61 | ||||
| -rw-r--r-- | src/irmd/ipcp.h | 8 | ||||
| -rw-r--r-- | src/irmd/main.c | 82 | ||||
| -rw-r--r-- | src/lib/ipcpd_messages.proto | 7 | ||||
| -rw-r--r-- | src/lib/irm.c | 66 | ||||
| -rw-r--r-- | src/lib/irmd_messages.proto | 31 | ||||
| -rw-r--r-- | src/tools/irm/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/tools/irm/irm_ipcp.c | 18 | ||||
| -rw-r--r-- | src/tools/irm/irm_ipcp_connect.c | 94 | ||||
| -rw-r--r-- | src/tools/irm/irm_ipcp_disconnect.c | 94 | ||||
| -rw-r--r-- | src/tools/irm/irm_ops.h | 6 | 
23 files changed, 619 insertions, 61 deletions
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 <dimitri.staessens@ugent.be> + *    Sander Vrijders   <sander.vrijders@ugent.be> + * + * 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 <dimitri.staessens@ugent.be> + *    Sander Vrijders   <sander.vrijders@ugent.be> + * + * 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);  | 
