From 269f25d3bac5ab871d8044935eacc15cfeadeec6 Mon Sep 17 00:00:00 2001 From: Dimitri Staessens Date: Sun, 12 Feb 2023 21:05:40 +0100 Subject: ipcpd: refactor IPCP configuration The ipcp configuration struct now has internal structures for the different IPCPs and for IPCP components of the unicast IPCP. Split the very long IPCP main loop into individual handler functions. Signed-off-by: Dimitri Staessens Signed-off-by: Sander Vrijders --- include/ouroboros/ipcp.h | 61 ++-- include/ouroboros/sockets.h.in | 4 + src/ipcpd/broadcast/main.c | 16 +- src/ipcpd/common/enroll.c | 50 +-- src/ipcpd/eth/eth.c | 31 +- src/ipcpd/ipcp.c | 631 ++++++++++++++++++++----------------- src/ipcpd/ipcp.h | 2 +- src/ipcpd/local/main.c | 6 +- src/ipcpd/udp/main.c | 48 +-- src/ipcpd/unicast/dt.c | 17 +- src/ipcpd/unicast/dt.h | 6 +- src/ipcpd/unicast/main.c | 22 +- src/lib/ipcp_config.proto | 42 ++- src/lib/irm.c | 70 ++-- src/tools/irm/irm_ipcp_bootstrap.c | 35 +- 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 = ð_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 */ -- cgit v1.2.3