diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ipcpd/broadcast/main.c | 16 | ||||
-rw-r--r-- | src/ipcpd/common/enroll.c | 50 | ||||
-rw-r--r-- | src/ipcpd/eth/eth.c | 31 | ||||
-rw-r--r-- | src/ipcpd/ipcp.c | 631 | ||||
-rw-r--r-- | src/ipcpd/ipcp.h | 2 | ||||
-rw-r--r-- | src/ipcpd/local/main.c | 6 | ||||
-rw-r--r-- | src/ipcpd/udp/main.c | 48 | ||||
-rw-r--r-- | src/ipcpd/unicast/dt.c | 17 | ||||
-rw-r--r-- | src/ipcpd/unicast/dt.h | 6 | ||||
-rw-r--r-- | src/ipcpd/unicast/main.c | 22 | ||||
-rw-r--r-- | src/lib/ipcp_config.proto | 42 | ||||
-rw-r--r-- | src/lib/irm.c | 70 | ||||
-rw-r--r-- | src/tools/irm/irm_ipcp_bootstrap.c | 35 |
13 files changed, 499 insertions, 477 deletions
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 */ |