diff options
| -rw-r--r-- | src/ipcpd/broadcast/main.c | 12 | ||||
| -rw-r--r-- | src/ipcpd/eth/eth.c | 9 | ||||
| -rw-r--r-- | src/ipcpd/ipcp.c | 138 | ||||
| -rw-r--r-- | src/ipcpd/ipcp.h | 4 | ||||
| -rw-r--r-- | src/ipcpd/local/main.c | 9 | ||||
| -rw-r--r-- | src/ipcpd/udp/main.c | 9 | ||||
| -rw-r--r-- | src/ipcpd/unicast/main.c | 12 | ||||
| -rw-r--r-- | src/lib/rib.c | 6 | 
8 files changed, 167 insertions, 32 deletions
diff --git a/src/ipcpd/broadcast/main.c b/src/ipcpd/broadcast/main.c index a2643029..522d1391 100644 --- a/src/ipcpd/broadcast/main.c +++ b/src/ipcpd/broadcast/main.c @@ -274,17 +274,11 @@ static struct ipcp_ops broadcast_ops = {  int main(int    argc,           char * argv[])  { -        if (ipcp_init(argc, argv, &broadcast_ops) < 0) { +        if (ipcp_init(argc, argv, &broadcast_ops, THIS_TYPE) < 0) {                  log_err("Failed to init IPCP.");                  goto fail_init;          } -        /* These components must be init at creation. */ -        if (rib_init(ipcpi.name)) { -                log_err("Failed to initialize RIB."); -                goto fail_rib_init; -        } -          if (notifier_init()) {                  log_err("Failed to initialize notifier component.");                  goto fail_notifier_init; @@ -324,8 +318,6 @@ int main(int    argc,          notifier_fini(); -        rib_fini(); -          ipcp_fini();          exit(EXIT_SUCCESS); @@ -339,8 +331,6 @@ int main(int    argc,   fail_connmgr_init:          notifier_fini();   fail_notifier_init: -        rib_fini(); - fail_rib_init:          ipcp_fini();   fail_init:          ipcp_create_r(-1); diff --git a/src/ipcpd/eth/eth.c b/src/ipcpd/eth/eth.c index a1eeb3fa..13a4a7e3 100644 --- a/src/ipcpd/eth/eth.c +++ b/src/ipcpd/eth/eth.c @@ -1283,6 +1283,13 @@ static int eth_ipcp_bootstrap(const struct ipcp_config * conf)          assert(conf);          assert(conf->type == THIS_TYPE); +        ipcpi.dir_hash_algo = conf->layer_info.dir_hash_algo; +        ipcpi.layer_name = strdup(conf->layer_info.layer_name); +        if (ipcpi.layer_name == NULL) { +                log_err("Failed to set layer name"); +                return -ENOMEM; +        } +          if (conf->dev == NULL) {                  log_err("Device name is NULL.");                  return -1; @@ -1833,7 +1840,7 @@ int main(int    argc,  {          int i; -        if (ipcp_init(argc, argv, ð_ops) < 0) +        if (ipcp_init(argc, argv, ð_ops, THIS_TYPE) < 0)                  goto fail_init;          if (eth_data_init() < 0) { diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c index 838ecda0..8c9d3525 100644 --- a/src/ipcpd/ipcp.c +++ b/src/ipcpd/ipcp.c @@ -41,7 +41,8 @@  #include "config.h" -#define OUROBOROS_PREFIX "ipcpd/ipcp" +#define OUROBOROS_PREFIX  "ipcpd/ipcp" +#define IPCP_INFO         "info"  #include <ouroboros/hash.h>  #include <ouroboros/logs.h> @@ -52,6 +53,7 @@  #include <ouroboros/dev.h>  #include <ouroboros/bitmap.h>  #include <ouroboros/np1_flow.h> +#include <ouroboros/rib.h>  #include "ipcp.h" @@ -63,6 +65,13 @@  #include <unistd.h>  #endif +char * info[LAYER_NAME_SIZE + 1] = { +        "_state", +        "_type", +        "_layer", +        NULL +}; +  struct cmd {          struct list_head next; @@ -97,6 +106,107 @@ void ipcp_hash_str(char *          buf,          buf[2 * i] = '\0';  } +static int ipcp_stat_read(const char * path, +                          char *       buf, +                          size_t       len) +{ +        if (len < LAYER_NAME_SIZE + 2) /* trailing \n */ +                return 0; + +        if (strcmp(path, info[0]) == 0) { /* _state */ +                enum ipcp_state state = ipcp_get_state(); +                if (state == IPCP_NULL) +                        strcpy(buf, "null\n"); +                else if (state == IPCP_INIT) +                        strcpy(buf, "init\n"); +                else if (state == IPCP_OPERATIONAL) +                        strcpy(buf, "operational\n"); +                else if (state == IPCP_SHUTDOWN) +                        strcpy(buf, "shutdown\n"); +                else +                        strcpy(buf, "bug\n"); +        } + +        if (strcmp(path, info[1]) == 0) { /* _type */ +                if (ipcpi.type == IPCP_LOCAL) +                        strcpy(buf, "local\n"); +                else if (ipcpi.type == IPCP_UNICAST) +                        strcpy(buf, "unicast\n"); +                else if (ipcpi.type == IPCP_BROADCAST) +                        strcpy(buf, "broadcast\n"); +                else if (ipcpi.type == IPCP_ETH_LLC) +                        strcpy(buf, "eth-llc\n"); +                else if (ipcpi.type == IPCP_ETH_DIX) +                        strcpy(buf, "eth-dix\n"); +                else if (ipcpi.type == IPCP_UDP) +                        strcpy(buf, "udp\n"); +                else +                        strcpy(buf, "bug\n"); +        } + +        if (strcmp(path, info[2]) == 0) { /* _layer */ +                memset(buf, 0, LAYER_NAME_SIZE + 1); +                if (ipcp_get_state() < IPCP_OPERATIONAL) +                        strcpy(buf, "(null)"); +                else +                        strcpy(buf, ipcpi.layer_name); + +                buf[strlen(buf)] = '\n'; +        } + +        return strlen(buf); +} + +static int ipcp_stat_readdir(char *** buf) +{ +        int  i = 0; + +        while (info[i] != NULL) +                i++; + +        *buf = malloc(sizeof(**buf) * i); +        if (*buf == NULL) +                goto fail; + +        i = 0; + +        while (info[i] != NULL) { +                (*buf)[i] = strdup(info[i]); +                if (*buf == NULL) +                        goto fail_dup; +                i++; +        } + +        return i; + fail_dup: +        while (--i > 0) +                free((*buf)[i]); + fail: +        free(*buf); + +        return -1; +} + +static int ipcp_stat_getattr(const char * path, +                             struct stat * st) +{ +        (void) path; + +        st->st_mode  = S_IFREG | 0755; +        st->st_nlink = 1; +        st->st_uid   = getuid(); +        st->st_gid   = getgid(); +        st->st_size  = LAYER_NAME_SIZE; + +        return 0; +} + +static struct rib_ops r_ops = { +        .read    = ipcp_stat_read, +        .readdir = ipcp_stat_readdir, +        .getattr = ipcp_stat_getattr +}; +  static void close_ptr(void * o)  {          close(*((int *) o)); @@ -263,6 +373,8 @@ static void * mainloop(void * o)                          default:                                  log_err("Unknown IPCP type: %d.",                                          conf_msg->ipcp_type); +                                ret_msg.result = -EIPCP; +                                goto exit; /* break from outer switch/case */                          }                          /* UDP and broadcast use fixed hash algorithm. */ @@ -293,8 +405,6 @@ static void * mainloop(void * o)                                          conf.layer_info.dir_hash_algo;                          } -                        ipcpi.dir_hash_algo = conf.layer_info.dir_hash_algo; -                          ret_msg.result = ipcpi.ops->ipcp_bootstrap(&conf);                          if (ret_msg.result == 0) {                                  ret_msg.layer_info = &layer_info; @@ -533,7 +643,7 @@ static void * mainloop(void * o)                          log_err("Don't know that message code");                          break;                  } - +        exit:                  pthread_cleanup_pop(true);                  pthread_cleanup_pop(false); @@ -596,7 +706,8 @@ static int parse_args(int    argc,  int ipcp_init(int               argc,                char **           argv, -              struct ipcp_ops * ops) +              struct ipcp_ops * ops, +              enum ipcp_type    type)  {          bool               log;          pthread_condattr_t cattr; @@ -609,6 +720,7 @@ int ipcp_init(int               argc,          ipcpi.irmd_fd   = -1;          ipcpi.state     = IPCP_NULL; +        ipcpi.type      = type;          ipcpi.sock_path = ipcp_sock_path(getpid());          if (ipcpi.sock_path == NULL) @@ -660,6 +772,11 @@ int ipcp_init(int               argc,                  goto fail_cmd_cond;          } +        if (rib_init(ipcpi.name)) { +                log_err("Failed to initialize RIB."); +                goto fail_rib_init; +        } +          list_head_init(&ipcpi.cmds);          ipcpi.alloc_id = -1; @@ -668,6 +785,8 @@ int ipcp_init(int               argc,          return 0; + fail_rib_init: +        pthread_cond_destroy(&ipcpi.cmd_cond);   fail_cmd_cond:          pthread_mutex_destroy(&ipcpi.cmd_lock);   fail_cmd_lock: @@ -709,6 +828,9 @@ int ipcp_boot()          ipcp_set_state(IPCP_INIT); +        if (rib_reg(IPCP_INFO, &r_ops)) +                goto fail_rib_reg; +          if (pthread_create(&ipcpi.acceptor, NULL, acceptloop, NULL)) {                  log_err("Failed to create acceptor thread.");                  ipcp_set_state(IPCP_NULL); @@ -717,7 +839,10 @@ int ipcp_boot()          return 0; +   fail_acceptor: +        rib_unreg(IPCP_INFO); + fail_rib_reg:          tpm_stop(ipcpi.tpm);   fail_tpm_start:          tpm_destroy(ipcpi.tpm); @@ -775,6 +900,9 @@ void ipcp_shutdown()  void ipcp_fini()  { + +        rib_fini(); +          close(ipcpi.sockfd);          if (unlink(ipcpi.sock_path))                  log_warn("Could not unlink %s.", ipcpi.sock_path); diff --git a/src/ipcpd/ipcp.h b/src/ipcpd/ipcp.h index 3ac0f74a..eff2ae12 100644 --- a/src/ipcpd/ipcp.h +++ b/src/ipcpd/ipcp.h @@ -35,6 +35,7 @@  enum ipcp_state {          IPCP_NULL = 0,          IPCP_INIT, +        /* Layer name must be set for states below. */          IPCP_OPERATIONAL,          IPCP_SHUTDOWN  }; @@ -116,7 +117,8 @@ extern struct ipcp {  int             ipcp_init(int               argc,                            char **           argv, -                          struct ipcp_ops * ops); +                          struct ipcp_ops * ops, +                          enum ipcp_type    type);  int             ipcp_boot(void); diff --git a/src/ipcpd/local/main.c b/src/ipcpd/local/main.c index 520f87fc..9c62c3cc 100644 --- a/src/ipcpd/local/main.c +++ b/src/ipcpd/local/main.c @@ -140,7 +140,12 @@ static int ipcp_local_bootstrap(const struct ipcp_config * conf)          assert(conf);          assert(conf->type == THIS_TYPE); -        (void) conf; +        ipcpi.dir_hash_algo = conf->layer_info.dir_hash_algo; +        ipcpi.layer_name = strdup(conf->layer_info.layer_name); +        if (ipcpi.layer_name == NULL) { +                log_err("Failed to set layer name"); +                return -ENOMEM; +        }          ipcp_set_state(IPCP_OPERATIONAL); @@ -340,7 +345,7 @@ static struct ipcp_ops local_ops = {  int main(int    argc,           char * argv[])  { -        if (ipcp_init(argc, argv, &local_ops) < 0) +        if (ipcp_init(argc, argv, &local_ops, THIS_TYPE) < 0)                  goto fail_init;          if (local_data_init() < 0) { diff --git a/src/ipcpd/udp/main.c b/src/ipcpd/udp/main.c index 4314b330..13db0c1f 100644 --- a/src/ipcpd/udp/main.c +++ b/src/ipcpd/udp/main.c @@ -573,6 +573,13 @@ static int ipcp_udp_bootstrap(const struct ipcp_config * conf)          assert(conf);          assert(conf->type == THIS_TYPE); +        ipcpi.dir_hash_algo = conf->layer_info.dir_hash_algo; +        ipcpi.layer_name = strdup(conf->layer_info.layer_name); +        if (ipcpi.layer_name == NULL) { +                log_err("Failed to set layer name"); +                return -ENOMEM; +        } +          if (inet_ntop(AF_INET, &conf->ip_addr, ipstr, INET_ADDRSTRLEN)              == NULL) {                  log_err("Failed to convert IP address"); @@ -1094,7 +1101,7 @@ int main(int    argc,  {          int i; -        if (ipcp_init(argc, argv, &udp_ops) < 0) +        if (ipcp_init(argc, argv, &udp_ops, THIS_TYPE) < 0)                  goto fail_init;          if (udp_data_init() < 0) { diff --git a/src/ipcpd/unicast/main.c b/src/ipcpd/unicast/main.c index 96df1664..018dd1c6 100644 --- a/src/ipcpd/unicast/main.c +++ b/src/ipcpd/unicast/main.c @@ -313,17 +313,11 @@ static struct ipcp_ops unicast_ops = {  int main(int    argc,           char * argv[])  { -        if (ipcp_init(argc, argv, &unicast_ops) < 0) { +        if (ipcp_init(argc, argv, &unicast_ops, THIS_TYPE) < 0) {                  log_err("Failed to init IPCP.");                  goto fail_init;          } -        /* These components must be init at creation. */ -        if (rib_init(ipcpi.name)) { -                log_err("Failed to initialize RIB."); -                goto fail_rib_init; -        } -          if (notifier_init()) {                  log_err("Failed to initialize notifier component.");                  goto fail_notifier_init; @@ -364,8 +358,6 @@ int main(int    argc,          notifier_fini(); -        rib_fini(); -          ipcp_fini();          exit(EXIT_SUCCESS); @@ -379,8 +371,6 @@ int main(int    argc,   fail_connmgr_init:          notifier_fini();   fail_notifier_init: -        rib_fini(); - fail_rib_init:         ipcp_fini();   fail_init:          ipcp_create_r(-1); diff --git a/src/lib/rib.c b/src/lib/rib.c index 0f3f3b3d..d9f59a3e 100644 --- a/src/lib/rib.c +++ b/src/lib/rib.c @@ -373,6 +373,9 @@ int rib_reg(const char *     path,          struct reg_comp *  rc;          struct list_head * p; +        if (strlen(rib.mnt) == 0) +                return 0; +          pthread_rwlock_wrlock(&rib.lock);          list_for_each(p, &rib.reg_comps) { @@ -417,6 +420,9 @@ void rib_unreg(const char * path)          struct list_head * p;          struct list_head * h; +        if (strlen(rib.mnt) == 0) +                return; +          pthread_rwlock_wrlock(&rib.lock);          list_for_each_safe(p, h, &rib.reg_comps) {  | 
