summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ipcpd/broadcast/main.c12
-rw-r--r--src/ipcpd/eth/eth.c9
-rw-r--r--src/ipcpd/ipcp.c138
-rw-r--r--src/ipcpd/ipcp.h4
-rw-r--r--src/ipcpd/local/main.c9
-rw-r--r--src/ipcpd/udp/main.c9
-rw-r--r--src/ipcpd/unicast/main.c12
-rw-r--r--src/lib/rib.c6
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, &eth_ops) < 0)
+ if (ipcp_init(argc, argv, &eth_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) {