diff options
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, | 
