summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ouroboros/ipcp.h61
-rw-r--r--include/ouroboros/sockets.h.in4
-rw-r--r--src/ipcpd/broadcast/main.c16
-rw-r--r--src/ipcpd/common/enroll.c50
-rw-r--r--src/ipcpd/eth/eth.c31
-rw-r--r--src/ipcpd/ipcp.c631
-rw-r--r--src/ipcpd/ipcp.h2
-rw-r--r--src/ipcpd/local/main.c6
-rw-r--r--src/ipcpd/udp/main.c48
-rw-r--r--src/ipcpd/unicast/dt.c17
-rw-r--r--src/ipcpd/unicast/dt.h6
-rw-r--r--src/ipcpd/unicast/main.c22
-rw-r--r--src/lib/ipcp_config.proto42
-rw-r--r--src/lib/irm.c70
-rw-r--r--src/tools/irm/irm_ipcp_bootstrap.c35
15 files changed, 537 insertions, 504 deletions
diff --git a/include/ouroboros/ipcp.h b/include/ouroboros/ipcp.h
index 857f4f5d..e2ae0c0e 100644
--- a/include/ouroboros/ipcp.h
+++ b/include/ouroboros/ipcp.h
@@ -29,10 +29,7 @@
#define LAYER_NAME_SIZE 255
-/*
- * NOTE: the IRMd uses this order to select an IPCP
- * for flow allocation.
- */
+/* NOTE: The IRMd uses this order to select an IPCP for flow allocation. */
enum ipcp_type {
IPCP_LOCAL = 0,
IPCP_UNICAST,
@@ -66,6 +63,31 @@ enum pol_dir_hash {
DIR_HASH_SHA3_512
};
+struct dt_config {
+ uint8_t addr_size;
+ uint8_t eid_size;
+ uint8_t max_ttl;
+ enum pol_routing routing_type;
+};
+
+/* IPCP configuration */
+struct uni_config {
+ struct dt_config dt;
+ enum pol_addr_auth addr_auth_type;
+ enum pol_cong_avoid cong_avoid;
+};
+
+struct eth_config {
+ char * dev;
+ uint16_t ethertype; /* DIX only*/
+};
+
+struct udp_config {
+ uint32_t ip_addr;
+ uint32_t dns_addr;
+ uint16_t port;
+};
+
/* Info reported back to the IRMd about the layer on enrollment */
struct layer_info {
char layer_name[LAYER_NAME_SIZE + 1];
@@ -74,29 +96,14 @@ struct layer_info {
/* Structure to configure the first IPCP */
struct ipcp_config {
- struct layer_info layer_info;
-
- enum ipcp_type type;
-
- /* Unicast */
- uint8_t addr_size;
- uint8_t eid_size;
- uint8_t max_ttl;
-
- enum pol_addr_auth addr_auth_type;
- enum pol_routing routing_type;
- enum pol_cong_avoid cong_avoid;
-
- /* UDP */
- uint32_t ip_addr;
- uint32_t dns_addr;
- uint16_t port;
-
- /* Ethernet */
- char * dev;
-
- /* Ethernet DIX */
- uint16_t ethertype;
+ struct layer_info layer_info;
+ enum ipcp_type type;
+
+ union {
+ struct uni_config unicast;
+ struct udp_config udp;
+ struct eth_config eth;
+ };
};
#endif /* OUROBOROS_IPCP_H */
diff --git a/include/ouroboros/sockets.h.in b/include/ouroboros/sockets.h.in
index 554fcc0a..b1e714f4 100644
--- a/include/ouroboros/sockets.h.in
+++ b/include/ouroboros/sockets.h.in
@@ -30,6 +30,10 @@
#include "ipcp_config.pb-c.h"
typedef IpcpConfigMsg ipcp_config_msg_t;
typedef LayerInfoMsg layer_info_msg_t;
+typedef DtConfigMsg dt_config_msg_t;
+typedef EthConfigMsg eth_config_msg_t;
+typedef UdpConfigMsg udp_config_msg_t;
+typedef UniConfigMsg uni_config_msg_t;
#include "irmd_messages.pb-c.h"
typedef IrmMsg irm_msg_t;
diff --git a/src/ipcpd/broadcast/main.c b/src/ipcpd/broadcast/main.c
index 2b8b90a5..d0becc63 100644
--- a/src/ipcpd/broadcast/main.c
+++ b/src/ipcpd/broadcast/main.c
@@ -56,36 +56,24 @@ struct ipcp ipcpi;
static int initialize_components(const struct ipcp_config * conf)
{
- ipcpi.layer_name = strdup(conf->layer_info.layer_name);
- if (ipcpi.layer_name == NULL) {
- log_err("Failed to set layer name.");
- goto fail_layer_name;
- }
-
+ strcpy(ipcpi.layer_name, conf->layer_info.layer_name);
ipcpi.dir_hash_algo = conf->layer_info.dir_hash_algo;
assert(ipcp_dir_hash_len() != 0);
if (dt_init()) {
log_err("Failed to initialize forwarding component.");
- goto fail_dt;
+ return -1;
}
ipcp_set_state(IPCP_INIT);
return 0;
-
- fail_dt:
- free(ipcpi.layer_name);
- fail_layer_name:
- return -1;
}
static void finalize_components(void)
{
dt_fini();
-
- free(ipcpi.layer_name);
}
static int start_components(void)
diff --git a/src/ipcpd/common/enroll.c b/src/ipcpd/common/enroll.c
index c71dc4cc..745829e7 100644
--- a/src/ipcpd/common/enroll.c
+++ b/src/ipcpd/common/enroll.c
@@ -74,7 +74,9 @@ static int send_rcv_enroll_msg(int fd)
ssize_t delta_t;
struct timespec t0;
struct timespec rtt;
-
+#ifdef BUILD_IPCP_UNICAST
+ uni_config_msg_t * uni_cfg_msg;
+#endif
req.code = ENROLL_CODE__ENROLL_REQ;
len = enroll_msg__get_packed_size(&req);
@@ -132,12 +134,14 @@ static int send_rcv_enroll_msg(int fd)
reply->conf->layer_info->layer_name);
enroll.conf.type = reply->conf->ipcp_type;
#ifdef BUILD_IPCP_UNICAST
- enroll.conf.addr_size = reply->conf->addr_size;
- enroll.conf.eid_size = reply->conf->eid_size;
- enroll.conf.max_ttl = reply->conf->max_ttl;
- enroll.conf.addr_auth_type = reply->conf->addr_auth_type;
- enroll.conf.routing_type = reply->conf->routing_type;
- enroll.conf.cong_avoid = reply->conf->cong_avoid;
+ uni_cfg_msg = reply->conf->unicast;
+
+ enroll.conf.unicast.dt.addr_size = uni_cfg_msg->dt->addr_size;
+ enroll.conf.unicast.dt.eid_size = uni_cfg_msg->dt->eid_size;
+ enroll.conf.unicast.dt.max_ttl = uni_cfg_msg->dt->max_ttl;
+ enroll.conf.unicast.dt.routing_type = uni_cfg_msg->dt->routing_type;
+ enroll.conf.unicast.addr_auth_type = uni_cfg_msg->addr_auth_type;
+ enroll.conf.unicast.cong_avoid = uni_cfg_msg->cong_avoid;
#endif
enroll.conf.layer_info.dir_hash_algo
= reply->conf->layer_info->dir_hash_algo;
@@ -151,6 +155,10 @@ static ssize_t enroll_pack(uint8_t ** buf)
enroll_msg_t msg = ENROLL_MSG__INIT;
ipcp_config_msg_t config = IPCP_CONFIG_MSG__INIT;
layer_info_msg_t layer_info = LAYER_INFO_MSG__INIT;
+#ifdef BUILD_IPCP_UNICAST
+ dt_config_msg_t dt_cfg_msg = DT_CONFIG_MSG__INIT;
+ uni_config_msg_t uni_cfg_msg = UNI_CONFIG_MSG__INIT;
+#endif
struct timespec now;
ssize_t len;
@@ -161,28 +169,24 @@ static ssize_t enroll_pack(uint8_t ** buf)
msg.t_sec = now.tv_sec;
msg.has_t_nsec = true;
msg.t_nsec = now.tv_nsec;
- msg.conf = &config;
- config.ipcp_type = enroll.conf.type;
+ config.ipcp_type = enroll.conf.type;
#ifdef BUILD_IPCP_UNICAST
- config.has_addr_size = true;
- config.addr_size = enroll.conf.addr_size;
- config.has_eid_size = true;
- config.eid_size = enroll.conf.eid_size;
- config.has_max_ttl = true;
- config.max_ttl = enroll.conf.max_ttl;
- config.has_addr_auth_type = true;
- config.addr_auth_type = enroll.conf.addr_auth_type;
- config.has_routing_type = true;
- config.routing_type = enroll.conf.routing_type;
- config.has_cong_avoid = true;
- config.cong_avoid = enroll.conf.cong_avoid;
+ dt_cfg_msg.addr_size = enroll.conf.unicast.dt.addr_size;
+ dt_cfg_msg.eid_size = enroll.conf.unicast.dt.eid_size;
+ dt_cfg_msg.max_ttl = enroll.conf.unicast.dt.max_ttl;
+ dt_cfg_msg.routing_type = enroll.conf.unicast.dt.routing_type;
+ uni_cfg_msg.dt = &dt_cfg_msg;
+ uni_cfg_msg.addr_auth_type = enroll.conf.unicast.addr_auth_type;
+ uni_cfg_msg.cong_avoid = enroll.conf.unicast.cong_avoid;
+ config.unicast = &uni_cfg_msg;
#endif
- config.layer_info = &layer_info;
-
layer_info.layer_name = (char *) enroll.conf.layer_info.layer_name;
layer_info.dir_hash_algo = enroll.conf.layer_info.dir_hash_algo;
+ config.layer_info = &layer_info;
+ msg.conf = &config;
+
len = enroll_msg__get_packed_size(&msg);
*buf = malloc(len);
diff --git a/src/ipcpd/eth/eth.c b/src/ipcpd/eth/eth.c
index 582351f8..6e0cb179 100644
--- a/src/ipcpd/eth/eth.c
+++ b/src/ipcpd/eth/eth.c
@@ -1281,31 +1281,27 @@ static int eth_ipcp_bootstrap(const struct ipcp_config * 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;
- }
+ strcpy(ipcpi.layer_name, conf->layer_info.layer_name);
- if (conf->dev == NULL) {
+ if (conf->eth.dev == NULL) {
log_err("Device name is NULL.");
return -1;
}
- if (strlen(conf->dev) >= IFNAMSIZ) {
- log_err("Invalid device name: %s.", conf->dev);
+ if (strlen(conf->eth.dev) >= IFNAMSIZ) {
+ log_err("Invalid device name: %s.", conf->eth.dev);
return -1;
}
memset(&ifr, 0, sizeof(ifr));
- strcpy(ifr.ifr_name, conf->dev);
+ strcpy(ifr.ifr_name, conf->eth.dev);
#ifdef BUILD_ETH_DIX
- if (conf->ethertype < 0x0600 || conf->ethertype == 0xFFFF) {
+ if (conf->eth.ethertype < 0x0600 || conf->eth.ethertype == 0xFFFF) {
log_err("Invalid Ethertype.");
return -1;
}
- eth_data.ethertype = htons(conf->ethertype);
+ eth_data.ethertype = htons(conf->eth.ethertype);
#endif
#if defined(__FreeBSD__) || defined(__APPLE__)
@@ -1315,9 +1311,9 @@ static int eth_ipcp_bootstrap(const struct ipcp_config * conf)
}
for (ifa = ifaddr, idx = 0; ifa != NULL; ifa = ifa->ifa_next, ++idx) {
- if (strcmp(ifa->ifa_name, conf->dev))
+ if (strcmp(ifa->ifa_name, conf->eth.dev))
continue;
- log_dbg("Interface %s found.", conf->dev);
+ log_dbg("Interface %s found.", conf->eth.dev);
#if defined(HAVE_NETMAP) || defined(HAVE_BPF)
memcpy(eth_data.hw_addr,
@@ -1352,7 +1348,8 @@ static int eth_ipcp_bootstrap(const struct ipcp_config * conf)
log_dbg("Device MTU is %d.", ifr.ifr_mtu);
eth_data.mtu = MIN((int) ETH_MTU_MAX, ifr.ifr_mtu);
- if (memcmp(conf->dev, "lo", 2) == 0 && eth_data.mtu > IPCP_ETH_LO_MTU) {
+ if (memcmp(conf->eth.dev, "lo", 2) == 0 &&
+ eth_data.mtu > IPCP_ETH_LO_MTU) {
log_dbg("Using loopback interface. MTU restricted to %d.",
IPCP_ETH_LO_MTU);
eth_data.mtu = IPCP_ETH_LO_MTU;
@@ -1376,7 +1373,7 @@ static int eth_ipcp_bootstrap(const struct ipcp_config * conf)
close(skfd);
- idx = if_nametoindex(conf->dev);
+ idx = if_nametoindex(conf->eth.dev);
if (idx == 0) {
log_err("Failed to retrieve interface index.");
return -1;
@@ -1386,7 +1383,7 @@ static int eth_ipcp_bootstrap(const struct ipcp_config * conf)
#if defined(HAVE_NETMAP)
strcpy(ifn, "netmap:");
- strcat(ifn, conf->dev);
+ strcat(ifn, conf->eth.dev);
eth_data.nmd = nm_open(ifn, NULL, 0, NULL);
if (eth_data.nmd == NULL) {
@@ -1526,7 +1523,7 @@ static int eth_ipcp_bootstrap(const struct ipcp_config * conf)
#if defined(BUILD_ETH_DIX)
log_dbg("Bootstrapped IPCP over DIX Ethernet with pid %d "
- "and Ethertype 0x%X.", getpid(), conf->ethertype);
+ "and Ethertype 0x%X.", getpid(), conf->eth.ethertype);
#elif defined(BUILD_ETH_LLC)
log_dbg("Bootstrapped IPCP over Ethernet with LLC with pid %d.",
getpid());
diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c
index de68f2f2..1e777637 100644
--- a/src/ipcpd/ipcp.c
+++ b/src/ipcpd/ipcp.c
@@ -261,23 +261,329 @@ static void free_msg(void * o)
ipcp_msg__free_unpacked((ipcp_msg_t *) o, NULL);
}
+
+static void handle_bootstrap(ipcp_config_msg_t * conf_msg,
+ layer_info_msg_t * layer_info_msg,
+ ipcp_msg_t * ret_msg)
+{
+ struct ipcp_config conf;
+ enum ipcp_type ipcp_type;
+ uni_config_msg_t * uni_cfg_msg;
+
+ if (ipcpi.ops->ipcp_bootstrap == NULL) {
+ log_err("Bootstrap unsupported.");
+ ret_msg->result = -ENOTSUP;
+ return;
+ }
+
+ if (ipcp_get_state() != IPCP_INIT) {
+ log_err("IPCP in wrong state.");
+ ret_msg->result = -EIPCPSTATE;
+ return;
+ }
+
+ conf.type = conf_msg->ipcp_type;
+
+ strcpy(conf.layer_info.layer_name, conf_msg->layer_info->layer_name);
+
+ ipcp_type = conf_msg->ipcp_type;
+
+ switch(ipcp_type) {
+ case IPCP_LOCAL:
+ break;
+ case IPCP_UNICAST:
+ uni_cfg_msg = conf_msg->unicast;
+
+ conf.unicast.dt.addr_size = uni_cfg_msg->dt->addr_size;
+ conf.unicast.dt.eid_size = uni_cfg_msg->dt->eid_size;
+ conf.unicast.dt.max_ttl = uni_cfg_msg->dt->max_ttl;
+ conf.unicast.dt.routing_type = uni_cfg_msg->dt->routing_type;
+ conf.unicast.addr_auth_type = uni_cfg_msg->addr_auth_type;
+ conf.unicast.cong_avoid = uni_cfg_msg->cong_avoid;
+ break;
+ case IPCP_ETH_DIX:
+ conf.eth.ethertype = conf_msg->eth->ethertype;
+ /* FALLTHRU */
+ case IPCP_ETH_LLC:
+ conf.eth.dev = conf_msg->eth->dev;
+ break;
+ case IPCP_UDP:
+ conf.udp.ip_addr = conf_msg->udp->ip_addr;
+ conf.udp.dns_addr = conf_msg->udp->dns_addr;
+ conf.udp.port = conf_msg->udp->port;
+ conf.layer_info.dir_hash_algo = HASH_MD5;
+ break;
+ case IPCP_BROADCAST:
+ conf.layer_info.dir_hash_algo = HASH_SHA3_256;
+ break;
+ default:
+ log_err("Unknown IPCP type: %d.", conf_msg->ipcp_type);
+ ret_msg->result = -EIPCP;
+ return;
+ }
+
+ /* UDP and broadcast use fixed hash algorithm. */
+ if (ipcp_type != IPCP_UDP && ipcp_type != IPCP_BROADCAST) {
+ switch(conf_msg->layer_info->dir_hash_algo) {
+ case DIR_HASH_SHA3_224:
+ conf.layer_info.dir_hash_algo = HASH_SHA3_224;
+ break;
+ case DIR_HASH_SHA3_256:
+ conf.layer_info.dir_hash_algo = HASH_SHA3_256;
+ break;
+ case DIR_HASH_SHA3_384:
+ conf.layer_info.dir_hash_algo = HASH_SHA3_384;
+ break;
+ case DIR_HASH_SHA3_512:
+ conf.layer_info.dir_hash_algo = HASH_SHA3_512;
+ break;
+ default:
+ assert(false);
+ }
+ }
+
+ ret_msg->result = ipcpi.ops->ipcp_bootstrap(&conf);
+ if (ret_msg->result == 0) {
+ layer_info_msg->layer_name = strdup(conf.layer_info.layer_name);
+ layer_info_msg->dir_hash_algo = conf.layer_info.dir_hash_algo;
+ ret_msg->layer_info = layer_info_msg;
+ }
+}
+
+static void handle_enroll(const char * dst,
+ layer_info_msg_t * layer_info_msg,
+ ipcp_msg_t * ret_msg)
+{
+ struct layer_info info;
+
+ if (ipcpi.ops->ipcp_enroll == NULL) {
+ log_err("Enroll unsupported.");
+ ret_msg->result = -ENOTSUP;
+ return;
+ }
+
+ if (ipcp_get_state() != IPCP_INIT) {
+ log_err("IPCP in wrong state.");
+ ret_msg->result = -EIPCPSTATE;
+ return;
+ }
+
+ ret_msg->result = ipcpi.ops->ipcp_enroll(dst, &info);
+ if (ret_msg->result == 0) {
+ layer_info_msg->layer_name = strdup(info.layer_name);
+ layer_info_msg->dir_hash_algo = info.dir_hash_algo;
+ ret_msg->layer_info = layer_info_msg;
+
+ }
+}
+
+static void handle_connect(const char * dst,
+ const char * comp,
+ qosspec_t qs,
+ ipcp_msg_t * ret_msg)
+{
+ if (ipcpi.ops->ipcp_connect == NULL) {
+ log_err("Connect unsupported.");
+ ret_msg->result = -ENOTSUP;
+ return;
+ }
+
+ ret_msg->result = ipcpi.ops->ipcp_connect(dst, comp, qs);
+}
+
+static void handle_disconnect(const char * dst,
+ const char * comp,
+ ipcp_msg_t * ret_msg)
+{
+ if (ipcpi.ops->ipcp_disconnect == NULL) {
+ log_err("Disconnect unsupported.");
+ ret_msg->result = -ENOTSUP;
+ return;
+ }
+
+ ret_msg->result = ipcpi.ops->ipcp_disconnect(dst, comp);
+}
+
+static void handle_reg(const uint8_t * hash,
+ ipcp_msg_t * ret_msg)
+{
+
+ if (ipcpi.ops->ipcp_reg == NULL) {
+ log_err("Registration unsupported.");
+ ret_msg->result = -ENOTSUP;
+ return;
+ }
+
+ ret_msg->result = ipcpi.ops->ipcp_reg(hash);
+}
+
+static void handle_unreg(const uint8_t * hash,
+ ipcp_msg_t * ret_msg)
+{
+ if (ipcpi.ops->ipcp_unreg == NULL) {
+ log_err("Unregistration unsupported.");
+ ret_msg->result = -ENOTSUP;
+ return;
+ }
+
+ ret_msg->result = ipcpi.ops->ipcp_unreg(hash);
+}
+
+static void handle_query(const uint8_t * hash,
+ ipcp_msg_t * ret_msg)
+{
+ if (ipcpi.ops->ipcp_query == NULL) {
+ log_err("Directory query unsupported.");
+ ret_msg->result = -ENOTSUP;
+ return;
+ }
+
+ if (ipcp_get_state() != IPCP_OPERATIONAL) {
+ log_err("IPCP in wrong state.");
+ ret_msg->result = -EIPCPSTATE;
+ return;
+ }
+
+ ret_msg->result = ipcpi.ops->ipcp_query(hash);
+}
+
+static void handle_flow_alloc(pid_t pid,
+ int flow_id,
+ uint8_t * dst,
+ qosspec_t qs,
+ void * data,
+ size_t len,
+ ipcp_msg_t * ret_msg)
+{
+ int fd;
+
+ if (ipcpi.ops->ipcp_flow_alloc == NULL) {
+ log_err("Flow allocation unsupported.");
+ ret_msg->result = -ENOTSUP;
+ return;
+ }
+
+ if (ipcp_get_state() != IPCP_OPERATIONAL) {
+ log_err("IPCP in wrong state.");
+ ret_msg->result = -EIPCPSTATE;
+ return;
+ }
+
+ fd = np1_flow_alloc(pid, flow_id);
+ if (fd < 0) {
+ log_err("Failed allocating fd on flow_id %d.", flow_id);
+ ret_msg->result = -EFLOWDOWN;
+ return;
+ }
+
+ ret_msg->result = ipcpi.ops->ipcp_flow_alloc(fd, dst, qs, data, len);
+}
+
+
+static void handle_flow_join(pid_t pid,
+ int flow_id,
+ const uint8_t * dst,
+ qosspec_t qs,
+ ipcp_msg_t * ret_msg)
+{
+ int fd;
+
+ if (ipcpi.ops->ipcp_flow_join == NULL) {
+ log_err("Broadcast unsupported.");
+ ret_msg->result = -ENOTSUP;
+ return;
+ }
+
+ if (ipcp_get_state() != IPCP_OPERATIONAL) {
+ log_err("IPCP in wrong state.");
+ ret_msg->result = -EIPCPSTATE;
+ return;
+ }
+
+ fd = np1_flow_alloc(pid, flow_id);
+ if (fd < 0) {
+ log_err("Failed allocating fd on flow_id %d.", flow_id);
+ ret_msg->result = -1;
+ return;
+ }
+
+ ret_msg->result = ipcpi.ops->ipcp_flow_join(fd, dst, qs);
+}
+
+static void handle_flow_alloc_resp(int resp,
+ int flow_id,
+ const void * data,
+ size_t len,
+ ipcp_msg_t * ret_msg)
+{
+ int fd = -1;
+
+ if (ipcpi.ops->ipcp_flow_alloc_resp == NULL) {
+ log_err("Flow_alloc_resp unsupported.");
+ ret_msg->result = -ENOTSUP;
+ return;
+ }
+
+ if (ipcp_get_state() != IPCP_OPERATIONAL) {
+ log_err("IPCP in wrong state.");
+ ret_msg->result = -EIPCPSTATE;
+ return;
+ }
+
+ if (resp == 0) {
+ fd = np1_flow_resp(flow_id);
+ if (fd < 0) {
+ log_warn("Flow_id %d is not known.", flow_id);
+ ret_msg->result = -1;
+ return;
+ }
+ }
+
+ ret_msg->result = ipcpi.ops->ipcp_flow_alloc_resp(fd, resp, data, len);
+}
+
+static void handle_flow_dealloc(int flow_id,
+ int timeo_sec,
+ ipcp_msg_t * ret_msg)
+{
+ int fd;
+
+ if (ipcpi.ops->ipcp_flow_dealloc == NULL) {
+ log_err("Flow deallocation unsupported.");
+ ret_msg->result = -ENOTSUP;
+ return;
+ }
+
+ if (ipcp_get_state() != IPCP_OPERATIONAL) {
+ log_err("IPCP in wrong state.");
+ ret_msg->result = -EIPCPSTATE;
+ return;
+ }
+
+ fd = np1_flow_dealloc(flow_id, timeo_sec);
+ if (fd < 0) {
+ log_warn("Could not deallocate flow_id %d.", flow_id);
+ ret_msg->result = -1;
+ return;
+ }
+
+ ret_msg->result = ipcpi.ops->ipcp_flow_dealloc(fd);
+}
+
+
static void * mainloop(void * o)
{
int sfd;
buffer_t buffer;
- struct ipcp_config conf;
- struct layer_info info;
- ipcp_config_msg_t * conf_msg;
ipcp_msg_t * msg;
(void) o;
while (true) {
- ipcp_msg_t ret_msg = IPCP_MSG__INIT;
- layer_info_msg_t layer_info = LAYER_INFO_MSG__INIT;
- int fd = -1;
- struct cmd * cmd;
- qosspec_t qs;
+ ipcp_msg_t ret_msg = IPCP_MSG__INIT;
+ layer_info_msg_t layer_info_msg = LAYER_INFO_MSG__INIT;
+ qosspec_t qs;
+ struct cmd * cmd;
ret_msg.code = IPCP_MSG_CODE__IPCP_REPLY;
@@ -308,327 +614,68 @@ static void * mainloop(void * o)
pthread_cleanup_push(__cleanup_close_ptr, &sfd);
pthread_cleanup_push(free_msg, msg);
+ ret_msg.has_result = true;
+
switch (msg->code) {
case IPCP_MSG_CODE__IPCP_BOOTSTRAP:
- ret_msg.has_result = true;
-
- if (ipcpi.ops->ipcp_bootstrap == NULL) {
- log_err("Bootstrap unsupported.");
- ret_msg.result = -ENOTSUP;
- break;
- }
-
- if (ipcp_get_state() != IPCP_INIT) {
- log_err("IPCP in wrong state.");
- ret_msg.result = -EIPCPSTATE;
- break;
- }
-
- conf_msg = msg->conf;
- conf.type = conf_msg->ipcp_type;
- strcpy(conf.layer_info.layer_name,
- conf_msg->layer_info->layer_name);
-
- switch(conf_msg->ipcp_type) {
- case IPCP_LOCAL:
- break;
- case IPCP_UNICAST:
- conf.addr_size = conf_msg->addr_size;
- conf.eid_size = conf_msg->eid_size;
- conf.max_ttl = conf_msg->max_ttl;
- conf.addr_auth_type = conf_msg->addr_auth_type;
- conf.routing_type = conf_msg->routing_type;
- conf.cong_avoid = conf_msg->cong_avoid;
- break;
- case IPCP_ETH_DIX:
- conf.ethertype = conf_msg->ethertype;
- /* FALLTHRU */
- case IPCP_ETH_LLC:
- conf.dev = conf_msg->dev;
- break;
- case IPCP_UDP:
- conf.ip_addr = conf_msg->ip_addr;
- conf.dns_addr = conf_msg->dns_addr;
- conf.port = conf_msg->port;
- conf.layer_info.dir_hash_algo = HASH_MD5;
- layer_info.dir_hash_algo = HASH_MD5;
- break;
- case IPCP_BROADCAST:
- conf.layer_info.dir_hash_algo = HASH_SHA3_256;
- layer_info.dir_hash_algo = HASH_SHA3_256;
- break;
- 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. */
- if (conf_msg->ipcp_type != IPCP_UDP &&
- conf_msg->ipcp_type != IPCP_BROADCAST) {
- switch(conf_msg->layer_info->dir_hash_algo) {
- case DIR_HASH_SHA3_224:
- conf.layer_info.dir_hash_algo =
- HASH_SHA3_224;
- break;
- case DIR_HASH_SHA3_256:
- conf.layer_info.dir_hash_algo =
- HASH_SHA3_256;
- break;
- case DIR_HASH_SHA3_384:
- conf.layer_info.dir_hash_algo =
- HASH_SHA3_384;
- break;
- case DIR_HASH_SHA3_512:
- conf.layer_info.dir_hash_algo =
- HASH_SHA3_512;
- break;
- default:
- assert(false);
- }
-
- layer_info.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;
- layer_info.layer_name =
- conf.layer_info.layer_name;
- }
+ handle_bootstrap(msg->conf, &layer_info_msg, &ret_msg);
break;
case IPCP_MSG_CODE__IPCP_ENROLL:
- ret_msg.has_result = true;
-
- if (ipcpi.ops->ipcp_enroll == NULL) {
- log_err("Enroll unsupported.");
- ret_msg.result = -ENOTSUP;
- break;
- }
-
- if (ipcp_get_state() != IPCP_INIT) {
- log_err("IPCP in wrong state.");
- ret_msg.result = -EIPCPSTATE;
- break;
- }
-
- ret_msg.result = ipcpi.ops->ipcp_enroll(msg->dst,
- &info);
- if (ret_msg.result == 0) {
- ret_msg.layer_info = &layer_info;
- layer_info.dir_hash_algo = info.dir_hash_algo;
- layer_info.layer_name = info.layer_name;
- }
+ handle_enroll(msg->dst, &layer_info_msg, &ret_msg);
break;
case IPCP_MSG_CODE__IPCP_CONNECT:
- ret_msg.has_result = true;
-
- if (ipcpi.ops->ipcp_connect == NULL) {
- log_err("Connect unsupported.");
- ret_msg.result = -ENOTSUP;
- break;
- }
-
qs = msg_to_spec(msg->qosspec);
- ret_msg.result = ipcpi.ops->ipcp_connect(msg->dst,
- msg->comp,
- qs);
+ handle_connect(msg->dst, msg->comp, qs, &ret_msg);
break;
case IPCP_MSG_CODE__IPCP_DISCONNECT:
- ret_msg.has_result = true;
-
- if (ipcpi.ops->ipcp_disconnect == NULL) {
- log_err("Disconnect unsupported.");
- ret_msg.result = -ENOTSUP;
- break;
- }
-
- ret_msg.result = ipcpi.ops->ipcp_disconnect(msg->dst,
- msg->comp);
+ handle_disconnect(msg->dst, msg->comp, &ret_msg);
break;
case IPCP_MSG_CODE__IPCP_REG:
- ret_msg.has_result = true;
-
- if (ipcpi.ops->ipcp_reg == NULL) {
- log_err("Registration unsupported.");
- ret_msg.result = -ENOTSUP;
- break;
- }
-
assert(msg->hash.len == ipcp_dir_hash_len());
-
- ret_msg.result =
- ipcpi.ops->ipcp_reg(msg->hash.data);
+ handle_reg(msg->hash.data, &ret_msg);
break;
case IPCP_MSG_CODE__IPCP_UNREG:
- ret_msg.has_result = true;
-
- if (ipcpi.ops->ipcp_unreg == NULL) {
- log_err("Unregistration unsupported.");
- ret_msg.result = -ENOTSUP;
- break;
- }
-
assert(msg->hash.len == ipcp_dir_hash_len());
-
- ret_msg.result =
- ipcpi.ops->ipcp_unreg(msg->hash.data);
+ handle_unreg(msg->hash.data, &ret_msg);
break;
case IPCP_MSG_CODE__IPCP_QUERY:
- ret_msg.has_result = true;
-
- if (ipcpi.ops->ipcp_query == NULL) {
- log_err("Directory query unsupported.");
- ret_msg.result = -ENOTSUP;
- break;
- }
-
assert(msg->hash.len == ipcp_dir_hash_len());
-
- if (ipcp_get_state() != IPCP_OPERATIONAL) {
- log_err("IPCP in wrong state.");
- ret_msg.result = -EIPCPSTATE;
- break;
- }
-
- ret_msg.result =
- ipcpi.ops->ipcp_query(msg->hash.data);
+ handle_query(msg->hash.data, &ret_msg);
break;
case IPCP_MSG_CODE__IPCP_FLOW_ALLOC:
- ret_msg.has_result = true;
-
- if (ipcpi.ops->ipcp_flow_alloc == NULL) {
- log_err("Flow allocation unsupported.");
- ret_msg.result = -ENOTSUP;
- break;
- }
-
assert(msg->hash.len == ipcp_dir_hash_len());
assert(msg->pk.len > 0 ? msg->pk.data != NULL
: msg->pk.data == NULL);
-
- if (ipcp_get_state() != IPCP_OPERATIONAL) {
- log_err("IPCP in wrong state.");
- ret_msg.result = -EIPCPSTATE;
- break;
- }
-
- fd = np1_flow_alloc(msg->pid,
- msg->flow_id);
- if (fd < 0) {
- log_err("Failed allocating fd on flow_id %d.",
- msg->flow_id);
- ret_msg.result = -1;
- break;
- }
-
qs = msg_to_spec(msg->qosspec);
- ret_msg.result =
- ipcpi.ops->ipcp_flow_alloc(fd,
- msg->hash.data,
- qs,
- msg->pk.data,
- msg->pk.len);
+ handle_flow_alloc(msg->pid, msg->flow_id,
+ msg->hash.data, qs,
+ msg->pk.data, msg->pk.len,
+ &ret_msg);
break;
case IPCP_MSG_CODE__IPCP_FLOW_JOIN:
- ret_msg.has_result = true;
-
- if (ipcpi.ops->ipcp_flow_join == NULL) {
- log_err("Broadcast unsupported.");
- ret_msg.result = -ENOTSUP;
- break;
- }
-
assert(msg->hash.len == ipcp_dir_hash_len());
-
- if (ipcp_get_state() != IPCP_OPERATIONAL) {
- log_err("IPCP in wrong state.");
- ret_msg.result = -EIPCPSTATE;
- break;
- }
-
- fd = np1_flow_alloc(msg->pid,
- msg->flow_id);
- if (fd < 0) {
- log_err("Failed allocating fd on flow_id %d.",
- msg->flow_id);
- ret_msg.result = -1;
- break;
- }
-
qs = msg_to_spec(msg->qosspec);
- ret_msg.result =
- ipcpi.ops->ipcp_flow_join(fd,
- msg->hash.data,
- qs);
+ handle_flow_join(msg->pid, msg->flow_id,
+ msg->hash.data, qs, &ret_msg);
break;
case IPCP_MSG_CODE__IPCP_FLOW_ALLOC_RESP:
- ret_msg.has_result = true;
- if (ipcpi.ops->ipcp_flow_alloc_resp == NULL) {
- log_err("Flow_alloc_resp unsupported.");
- ret_msg.result = -ENOTSUP;
- break;
- }
-
- if (ipcp_get_state() != IPCP_OPERATIONAL) {
- log_err("IPCP in wrong state.");
- ret_msg.result = -EIPCPSTATE;
- break;
- }
-
- if (!msg->response) {
- fd = np1_flow_resp(msg->flow_id);
- if (fd < 0) {
- log_warn("Port_id %d is not known.",
- msg->flow_id);
- ret_msg.result = -1;
- break;
- }
- }
-
assert(msg->pk.len > 0 ? msg->pk.data != NULL
- : msg->pk.data == NULL);
+ : msg->pk.data == NULL);
- ret_msg.result =
- ipcpi.ops->ipcp_flow_alloc_resp(fd,
- msg->response,
- msg->pk.data,
- msg->pk.len);
+ handle_flow_alloc_resp(msg->response, msg->flow_id,
+ msg->pk.data, msg->pk.len,
+ &ret_msg);
break;
case IPCP_MSG_CODE__IPCP_FLOW_DEALLOC:
- ret_msg.has_result = true;
- if (ipcpi.ops->ipcp_flow_dealloc == NULL) {
- log_err("Flow deallocation unsupported.");
- ret_msg.result = -ENOTSUP;
- break;
- }
-
- if (ipcp_get_state() != IPCP_OPERATIONAL) {
- log_err("IPCP in wrong state.");
- ret_msg.result = -EIPCPSTATE;
- break;
- }
-
- fd = np1_flow_dealloc(msg->flow_id, msg->timeo_sec);
- if (fd < 0) {
- log_warn("Could not deallocate flow_id %d.",
- msg->flow_id);
- ret_msg.result = -1;
- break;
- }
-
- ret_msg.result =
- ipcpi.ops->ipcp_flow_dealloc(fd);
+ handle_flow_dealloc(msg->flow_id, msg->timeo_sec,
+ &ret_msg);
break;
default:
- ret_msg.has_result = true;
ret_msg.result = -1;
log_err("Unknown message code: %d.", msg->code);
break;
}
- exit:
+
pthread_cleanup_pop(true);
pthread_cleanup_pop(false);
@@ -650,12 +697,16 @@ static void * mainloop(void * o)
ipcp_msg__pack(&ret_msg, buffer.data);
+ if (ret_msg.layer_info != NULL)
+ free(ret_msg.layer_info->layer_name);
+
pthread_cleanup_push(__cleanup_close_ptr, &sfd);
+ pthread_cleanup_push(free, buffer.data)
if (write(sfd, buffer.data, buffer.len) == -1)
log_warn("Failed to send reply message");
- free(buffer.data);
+ pthread_cleanup_pop(true);
pthread_cleanup_pop(true);
tpm_inc(ipcpi.tpm);
diff --git a/src/ipcpd/ipcp.h b/src/ipcpd/ipcp.h
index 37d5b972..9e7a7223 100644
--- a/src/ipcpd/ipcp.h
+++ b/src/ipcpd/ipcp.h
@@ -85,7 +85,7 @@ extern struct ipcp {
char * name;
enum ipcp_type type;
- char * layer_name;
+ char layer_name[LAYER_NAME_SIZE + 1];
uint64_t dt_addr;
diff --git a/src/ipcpd/local/main.c b/src/ipcpd/local/main.c
index c1e95d23..f43d4713 100644
--- a/src/ipcpd/local/main.c
+++ b/src/ipcpd/local/main.c
@@ -145,11 +145,7 @@ static int ipcp_local_bootstrap(const struct ipcp_config * 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;
- }
+ strcpy(ipcpi.layer_name,conf->layer_info.layer_name);
ipcp_set_state(IPCP_OPERATIONAL);
diff --git a/src/ipcpd/udp/main.c b/src/ipcpd/udp/main.c
index fe25e17e..1a7725c1 100644
--- a/src/ipcpd/udp/main.c
+++ b/src/ipcpd/udp/main.c
@@ -591,6 +591,12 @@ static void * ipcp_udp_packet_writer(void * o)
return (void *) 1;
}
+static const char * inet4_ntop(const void * addr,
+ char * buf)
+{
+ return inet_ntop(AF_INET, &addr, buf, INET_ADDRSTRLEN);
+}
+
static int ipcp_udp_bootstrap(const struct ipcp_config * conf)
{
char ipstr[INET_ADDRSTRLEN];
@@ -602,21 +608,15 @@ static int ipcp_udp_bootstrap(const struct ipcp_config * 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;
- }
+ strcpy(ipcpi.layer_name, conf->layer_info.layer_name);
- if (inet_ntop(AF_INET, &conf->ip_addr, ipstr, INET_ADDRSTRLEN)
- == NULL) {
+ if (inet4_ntop(&conf->udp.ip_addr, ipstr) == NULL) {
log_err("Failed to convert IP address");
return -1;
}
- if (conf->dns_addr != 0) {
- if (inet_ntop(AF_INET, &conf->dns_addr, dnsstr, INET_ADDRSTRLEN)
- == NULL) {
+ if (conf->udp.dns_addr != 0) {
+ if (inet4_ntop(&conf->udp.dns_addr, dnsstr) == NULL) {
log_err("Failed to convert DNS address");
return -1;
}
@@ -636,15 +636,15 @@ static int ipcp_udp_bootstrap(const struct ipcp_config * conf)
memset((char *) &udp_data.s_saddr, 0, sizeof(udp_data.s_saddr));
udp_data.s_saddr.sin_family = AF_INET;
- udp_data.s_saddr.sin_addr.s_addr = conf->ip_addr;
- udp_data.s_saddr.sin_port = htons(conf->port);
+ udp_data.s_saddr.sin_addr.s_addr = conf->udp.ip_addr;
+ udp_data.s_saddr.sin_port = htons(conf->udp.port);
if (bind(udp_data.s_fd, SADDR, SADDR_SIZE) < 0) {
log_err("Couldn't bind to %s.", ipstr);
goto fail_bind;
}
- udp_data.dns_addr = conf->dns_addr;
+ udp_data.dns_addr = conf->udp.dns_addr;
ipcp_set_state(IPCP_OPERATIONAL);
@@ -670,11 +670,11 @@ static int ipcp_udp_bootstrap(const struct ipcp_config * conf)
}
}
- sprintf(portstr, "%d", conf->port);
+ sprintf(portstr, "%d", conf->udp.port);
log_dbg("Bootstrapped IPCP over UDP with pid %d.", getpid());
log_dbg("Bound to IP address %s.", ipstr);
- log_dbg("Using port %u.", conf->port);
+ log_dbg("Using port %u.", conf->udp.port);
log_dbg("DNS server address is %s.", dnsstr);
return 0;
@@ -759,7 +759,7 @@ static uint32_t ddns_resolve(char * name,
char * addr_str = "Address:";
uint32_t ip_addr = 0;
- if (inet_ntop(AF_INET, &dns_addr, dnsstr, INET_ADDRSTRLEN) == NULL)
+ if (inet4_ntop(&dns_addr, dnsstr) == NULL)
return 0;
if (pipe(pipe_fd)) {
@@ -855,14 +855,12 @@ static int ipcp_udp_reg(const uint8_t * hash)
if (dns_addr != 0) {
ip_addr = udp_data.s_saddr.sin_addr.s_addr;
- if (inet_ntop(AF_INET, &ip_addr,
- ipstr, INET_ADDRSTRLEN) == NULL) {
+ if (inet4_ntop(&ip_addr, ipstr) == NULL) {
free(hashstr);
return -1;
}
- if (inet_ntop(AF_INET, &dns_addr,
- dnsstr, INET_ADDRSTRLEN) == NULL) {
+ if (inet4_ntop(&dns_addr, dnsstr) == NULL) {
free(hashstr);
return -1;
}
@@ -908,8 +906,7 @@ static int ipcp_udp_unreg(const uint8_t * hash)
dns_addr = udp_data.dns_addr;
if (dns_addr != 0) {
- if (inet_ntop(AF_INET, &dns_addr, dnsstr, INET_ADDRSTRLEN)
- == NULL) {
+ if (inet4_ntop(&dns_addr, dnsstr) == NULL) {
free(hashstr);
return -1;
}
@@ -1002,13 +999,16 @@ static int ipcp_udp_flow_alloc(int fd,
assert(dst);
if (!shim_data_dir_has(udp_data.shim_data, dst)) {
- log_dbg("Could not resolve destination.");
+ log_err("Could not resolve destination.");
return -1;
}
ip_addr = (uint32_t) shim_data_dir_get_addr(udp_data.shim_data, dst);
- inet_ntop(AF_INET, &ip_addr, ipstr, INET_ADDRSTRLEN);
+ if (inet4_ntop(&ip_addr, ipstr) == NULL) {
+ log_err("Could not convert IP address.");
+ return -1;
+ }
log_dbg("Destination UDP ipcp resolved at %s.", ipstr);
memset((char *) &r_saddr, 0, sizeof(r_saddr));
diff --git a/src/ipcpd/unicast/dt.c b/src/ipcpd/unicast/dt.c
index 48940a2b..60975aed 100644
--- a/src/ipcpd/unicast/dt.c
+++ b/src/ipcpd/unicast/dt.c
@@ -563,10 +563,7 @@ static void * dt_conn_handle(void * o)
return 0;
}
-int dt_init(enum pol_routing pr,
- uint8_t addr_size,
- uint8_t eid_size,
- uint8_t max_ttl)
+int dt_init(struct dt_config cfg)
{
int i;
int j;
@@ -582,14 +579,14 @@ int dt_init(enum pol_routing pr,
info.pref_syntax = PROTO_FIXED;
info.addr = ipcpi.dt_addr;
- if (eid_size != 8) { /* only support 64 bits from now */
+ if (cfg.eid_size != 8) { /* only support 64 bits from now */
log_warn("Invalid EID size. Only 64 bit is supported.");
- eid_size = 8;
+ cfg.eid_size = 8;
}
- dt_pci_info.addr_size = addr_size;
- dt_pci_info.eid_size = eid_size;
- dt_pci_info.max_ttl = max_ttl;
+ dt_pci_info.addr_size = cfg.addr_size;
+ dt_pci_info.eid_size = cfg.eid_size;
+ dt_pci_info.max_ttl = cfg.max_ttl;
dt_pci_info.qc_o = dt_pci_info.addr_size;
dt_pci_info.ttl_o = dt_pci_info.qc_o + QOS_LEN;
@@ -607,7 +604,7 @@ int dt_init(enum pol_routing pr,
goto fail_connmgr_comp_init;
}
- pp = routing_init(pr);
+ pp = routing_init(cfg.routing_type);
if (pp < 0) {
log_err("Failed to init routing.");
goto fail_routing;
diff --git a/src/ipcpd/unicast/dt.h b/src/ipcpd/unicast/dt.h
index 5ad8cceb..478c79ea 100644
--- a/src/ipcpd/unicast/dt.h
+++ b/src/ipcpd/unicast/dt.h
@@ -31,11 +31,7 @@
#define DT_PROTO "dtp"
#define INVALID_ADDR 0
-int dt_init(enum pol_routing pr,
- uint8_t addr_size,
- uint8_t eid_size,
- uint8_t max_ttl
-);
+int dt_init(struct dt_config cfg);
void dt_fini(void);
diff --git a/src/ipcpd/unicast/main.c b/src/ipcpd/unicast/main.c
index 4d2ef1f2..1318ec2f 100644
--- a/src/ipcpd/unicast/main.c
+++ b/src/ipcpd/unicast/main.c
@@ -59,18 +59,13 @@ struct ipcp ipcpi;
static int initialize_components(const struct ipcp_config * conf)
{
- ipcpi.layer_name = strdup(conf->layer_info.layer_name);
- if (ipcpi.layer_name == NULL) {
- log_err("Failed to set layer name.");
- goto fail_layer_name;
- }
-
+ strcpy(ipcpi.layer_name, conf->layer_info.layer_name);
ipcpi.dir_hash_algo = conf->layer_info.dir_hash_algo;
assert(ipcp_dir_hash_len() != 0);
- if (addr_auth_init(conf->addr_auth_type,
- &conf->addr_size)) {
+ if (addr_auth_init(conf->unicast.addr_auth_type,
+ &conf->unicast.dt.addr_size)) {
log_err("Failed to init address authority.");
goto fail_addr_auth;
}
@@ -83,15 +78,12 @@ static int initialize_components(const struct ipcp_config * conf)
log_dbg("IPCP got address %" PRIu64 ".", ipcpi.dt_addr);
- if (ca_init(conf->cong_avoid)) {
+ if (ca_init(conf->unicast.cong_avoid)) {
log_err("Failed to initialize congestion avoidance.");
goto fail_ca;
}
- if (dt_init(conf->routing_type,
- conf->addr_size,
- conf->eid_size,
- conf->max_ttl)) {
+ if (dt_init(conf->unicast.dt)) {
log_err("Failed to initialize data transfer component.");
goto fail_dt;
}
@@ -119,8 +111,6 @@ static int initialize_components(const struct ipcp_config * conf)
fail_ca:
addr_auth_fini();
fail_addr_auth:
- free(ipcpi.layer_name);
- fail_layer_name:
return -1;
}
@@ -135,8 +125,6 @@ static void finalize_components(void)
ca_fini();
addr_auth_fini();
-
- free(ipcpi.layer_name);
}
static int start_components(void)
diff --git a/src/lib/ipcp_config.proto b/src/lib/ipcp_config.proto
index 812d909b..c6481b09 100644
--- a/src/lib/ipcp_config.proto
+++ b/src/lib/ipcp_config.proto
@@ -27,24 +27,36 @@ message layer_info_msg {
required uint32 dir_hash_algo = 2;
}
+message dt_config_msg {
+ required uint32 addr_size = 1;
+ required uint32 eid_size = 2;
+ required uint32 max_ttl = 3;
+ required uint32 routing_type = 4;
+}
+
+message uni_config_msg {
+ required dt_config_msg dt = 1;
+ required uint32 addr_auth_type = 2;
+ required uint32 cong_avoid = 3;
+}
+
+message eth_config_msg {
+ required string dev = 1;
+ optional uint32 ethertype = 2;
+}
+
+message udp_config_msg {
+ required uint32 ip_addr = 1;
+ required uint32 port = 2;
+ required uint32 dns_addr = 3; /* set to 0 if unused */
+}
+
message ipcp_config_msg {
required layer_info_msg layer_info = 1;
required int32 ipcp_type = 2;
- // Config for unicast IPCP
- optional uint32 addr_size = 3;
- optional uint32 eid_size = 4;
- optional uint32 max_ttl = 5;
- optional uint32 addr_auth_type = 6;
- optional uint32 routing_type = 7;
- optional uint32 cong_avoid = 8;
- // Config for UDP
- optional uint32 ip_addr = 9;
- optional uint32 dns_addr = 10;
- optional uint32 port = 11;
- // Config for the Ethernet
- optional string dev = 12;
- // Config for DIX Ethernet
- optional uint32 ethertype = 13;
+ optional uni_config_msg unicast = 3;
+ optional udp_config_msg udp = 4;
+ optional eth_config_msg eth = 5;
}
enum enroll_code {
diff --git a/src/lib/irm.c b/src/lib/irm.c
index dbc1c556..2a8aa05c 100644
--- a/src/lib/irm.c
+++ b/src/lib/irm.c
@@ -98,11 +98,15 @@ int irm_destroy_ipcp(pid_t pid)
int irm_bootstrap_ipcp(pid_t pid,
const struct ipcp_config * conf)
{
- irm_msg_t msg = IRM_MSG__INIT;
- ipcp_config_msg_t config = IPCP_CONFIG_MSG__INIT;
- layer_info_msg_t layer_info = LAYER_INFO_MSG__INIT;
- irm_msg_t * recv_msg = NULL;
- int ret = -1;
+ irm_msg_t msg = IRM_MSG__INIT;
+ ipcp_config_msg_t cfg_msg = IPCP_CONFIG_MSG__INIT;
+ layer_info_msg_t layer_info_msg = LAYER_INFO_MSG__INIT;
+ dt_config_msg_t dt_cfg_msg = DT_CONFIG_MSG__INIT;
+ uni_config_msg_t uni_cfg_msg = UNI_CONFIG_MSG__INIT;
+ eth_config_msg_t eth_cfg_msg = ETH_CONFIG_MSG__INIT;
+ udp_config_msg_t udp_cfg_msg = UDP_CONFIG_MSG__INIT;
+ irm_msg_t * recv_msg = NULL;
+ int ret = -1;
if (pid == -1 || conf == NULL)
return -EINVAL;
@@ -111,54 +115,46 @@ int irm_bootstrap_ipcp(pid_t pid,
msg.has_pid = true;
msg.pid = pid;
- config.layer_info = &layer_info;
- msg.conf = &config;
- layer_info.layer_name = (char *) conf->layer_info.layer_name;
-
- config.ipcp_type = conf->type;
-
- if (conf->type != IPCP_UDP)
- layer_info.dir_hash_algo = conf->layer_info.dir_hash_algo;
+ cfg_msg.ipcp_type = conf->type;
+ layer_info_msg.layer_name = (char *) conf->layer_info.layer_name;
+ layer_info_msg.dir_hash_algo = conf->layer_info.dir_hash_algo;
switch (conf->type) {
case IPCP_UNICAST:
- config.has_addr_size = true;
- config.addr_size = conf->addr_size;
- config.has_eid_size = true;
- config.eid_size = conf->eid_size;
- config.has_max_ttl = true;
- config.max_ttl = conf->max_ttl;
- config.has_addr_auth_type = true;
- config.addr_auth_type = conf->addr_auth_type;
- config.has_routing_type = true;
- config.routing_type = conf->routing_type;
- config.has_cong_avoid = true;
- config.cong_avoid = conf->cong_avoid;
+ dt_cfg_msg.addr_size = conf->unicast.dt.addr_size;
+ dt_cfg_msg.eid_size = conf->unicast.dt.eid_size;
+ dt_cfg_msg.max_ttl = conf->unicast.dt.max_ttl;
+ dt_cfg_msg.routing_type = conf->unicast.dt.routing_type;
+ uni_cfg_msg.dt = &dt_cfg_msg;
+ uni_cfg_msg.addr_auth_type = conf->unicast.addr_auth_type;
+ uni_cfg_msg.cong_avoid = conf->unicast.cong_avoid;
+ cfg_msg.unicast = &uni_cfg_msg;
break;
case IPCP_UDP:
- config.has_ip_addr = true;
- config.ip_addr = conf->ip_addr;
- config.has_dns_addr = true;
- config.dns_addr = conf->dns_addr;
- config.has_port = true;
- config.port = conf->port;
+ udp_cfg_msg.ip_addr = conf->udp.ip_addr;
+ udp_cfg_msg.dns_addr = conf->udp.dns_addr;
+ udp_cfg_msg.port = conf->udp.port;
+ cfg_msg.udp = &udp_cfg_msg;
break;
case IPCP_LOCAL:
/* FALLTHRU */
case IPCP_BROADCAST:
break;
- case IPCP_ETH_LLC:
- config.dev = conf->dev;
- break;
case IPCP_ETH_DIX:
- config.dev = conf->dev;
- config.has_ethertype = true;
- config.ethertype = conf->ethertype;
+ eth_cfg_msg.has_ethertype = true;
+ eth_cfg_msg.ethertype = conf->eth.ethertype;
+ /* FALLTHRU */
+ case IPCP_ETH_LLC:
+ eth_cfg_msg.dev = conf->eth.dev;
+ cfg_msg.eth = &eth_cfg_msg;
break;
default:
return -EIPCPTYPE;
}
+ cfg_msg.layer_info = &layer_info_msg;
+ msg.conf = &cfg_msg;
+
recv_msg = send_recv_irm_msg(&msg);
if (recv_msg == NULL)
return -EIRMD;
diff --git a/src/tools/irm/irm_ipcp_bootstrap.c b/src/tools/irm/irm_ipcp_bootstrap.c
index 32b3cea3..2e90b82c 100644
--- a/src/tools/irm/irm_ipcp_bootstrap.c
+++ b/src/tools/irm/irm_ipcp_bootstrap.c
@@ -292,6 +292,7 @@ int do_bootstrap_ipcp(int argc,
printf("Types do not match.\n\n");
goto fail;
}
+
conf.type = ipcps[i].type;
if (autobind && (conf.type != IPCP_UNICAST &&
@@ -302,40 +303,36 @@ int do_bootstrap_ipcp(int argc,
}
if (strlen(layer) > LAYER_NAME_SIZE) {
- printf("Layer name too big.\n\n");
+ printf("Layer name too long.\n\n");
goto fail_usage;
}
strcpy(conf.layer_info.layer_name, layer);
- if (conf.type != IPCP_UDP)
- conf.layer_info.dir_hash_algo = hash_algo;
+ conf.layer_info.dir_hash_algo = hash_algo;
switch (conf.type) {
case IPCP_UNICAST:
- conf.addr_size = addr_size;
- conf.eid_size = eid_size;
- conf.max_ttl = max_ttl;
- conf.addr_auth_type = addr_auth_type;
- conf.routing_type = routing_type;
- conf.cong_avoid = cong_avoid;
+ conf.unicast.dt.addr_size = addr_size;
+ conf.unicast.dt.eid_size = eid_size;
+ conf.unicast.dt.max_ttl = max_ttl;
+ conf.unicast.dt.routing_type = routing_type;
+ conf.unicast.addr_auth_type = addr_auth_type;
+ conf.unicast.cong_avoid = cong_avoid;
break;
case IPCP_UDP:
if (ip_addr == 0)
goto fail_usage;
- conf.ip_addr = ip_addr;
- conf.dns_addr = dns_addr;
- conf.port = port;
- break;
- case IPCP_ETH_LLC:
- if (dev == NULL)
- goto fail_usage;
- conf.dev = dev;
+ conf.udp.ip_addr = ip_addr;
+ conf.udp.dns_addr = dns_addr;
+ conf.udp.port = port;
break;
case IPCP_ETH_DIX:
+ conf.eth.ethertype = ethertype;
+ /* FALLTHRU */
+ case IPCP_ETH_LLC:
if (dev == NULL)
goto fail_usage;
- conf.dev = dev;
- conf.ethertype = ethertype;
+ conf.eth.dev = dev;
break;
case IPCP_BROADCAST:
/* FALLTHRU */