summaryrefslogtreecommitdiff
path: root/src/ipcpd/ipcp.c
diff options
context:
space:
mode:
authorDimitri Staessens <dimitri@ouroboros.rocks>2021-06-18 17:37:11 +0200
committerSander Vrijders <sander@ouroboros.rocks>2021-06-21 08:45:25 +0200
commit1a13d42a0792a4a12a40c813072355502e87c42f (patch)
tree9c86f115e7f511482d178956f67af432aa9ee39a /src/ipcpd/ipcp.c
parent7b13504e2a47a40ae7e5283de41d48ca3f7efb53 (diff)
downloadouroboros-1a13d42a0792a4a12a40c813072355502e87c42f.tar.gz
ouroboros-1a13d42a0792a4a12a40c813072355502e87c42f.zip
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 <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
Diffstat (limited to 'src/ipcpd/ipcp.c')
-rw-r--r--src/ipcpd/ipcp.c138
1 files changed, 133 insertions, 5 deletions
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);