From 1a13d42a0792a4a12a40c813072355502e87c42f Mon Sep 17 00:00:00 2001 From: Dimitri Staessens Date: Fri, 18 Jun 2021 17:37:11 +0200 Subject: ipcpd: Move RIB initialization to common ground This moves Resource Information Base (RIB) initialization into the ipcp_init() function, so all IPCPs initialize a RIB. The RIB not shows some common IPCP information, such as the IPCP name, IPCP state and the layer name if the IPCP is part of a layer. The initialization of the hash algorithm and layer name was moved out of the common ipcp source because IPCPs may only know this information after enrollment. Some IPCPs were not even storing this information. Signed-off-by: Dimitri Staessens Signed-off-by: Sander Vrijders --- src/ipcpd/broadcast/main.c | 12 +--- src/ipcpd/eth/eth.c | 9 ++- src/ipcpd/ipcp.c | 138 +++++++++++++++++++++++++++++++++++++++++++-- src/ipcpd/ipcp.h | 4 +- src/ipcpd/local/main.c | 9 ++- src/ipcpd/udp/main.c | 9 ++- src/ipcpd/unicast/main.c | 12 +--- 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 #include @@ -52,6 +53,7 @@ #include #include #include +#include #include "ipcp.h" @@ -63,6 +65,13 @@ #include #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) { -- cgit v1.2.3