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) { |