From 2d88fdaaa018d607eca5ce057dfbdf41beb6125b Mon Sep 17 00:00:00 2001 From: Sander Vrijders Date: Mon, 31 Oct 2016 19:47:45 +0100 Subject: ipcpd: normal: Add policy for obtaining a flat address This adds a policy for obtaining a flat address, and thus also the infrastructure for policies in the IPCP. The IPCP should check if the address is available; this is currently not there yet. --- include/ouroboros/irm_config.h | 6 +++ src/ipcpd/ipcp.c | 1 + src/ipcpd/normal/CMakeLists.txt | 2 + src/ipcpd/normal/addr_auth.c | 78 ++++++++++++++++++++++++++++++++++++++ src/ipcpd/normal/addr_auth.h | 39 +++++++++++++++++++ src/ipcpd/normal/flat.c | 63 ++++++++++++++++++++++++++++++ src/ipcpd/normal/flat.h | 30 +++++++++++++++ src/ipcpd/normal/ribmgr.c | 48 ++++++++++++++++------- src/ipcpd/normal/ribmgr.h | 3 +- src/ipcpd/normal/shm_pci.h | 1 + src/ipcpd/normal/static_info.proto | 2 +- src/lib/dif_config.proto | 7 ++-- src/lib/irm.c | 2 + src/tools/irm/irm_ipcp_bootstrap.c | 12 +++++- 14 files changed, 275 insertions(+), 19 deletions(-) create mode 100644 src/ipcpd/normal/addr_auth.c create mode 100644 src/ipcpd/normal/addr_auth.h create mode 100644 src/ipcpd/normal/flat.c create mode 100644 src/ipcpd/normal/flat.h diff --git a/include/ouroboros/irm_config.h b/include/ouroboros/irm_config.h index ba58f2f7..6b759633 100644 --- a/include/ouroboros/irm_config.h +++ b/include/ouroboros/irm_config.h @@ -39,6 +39,10 @@ enum ipcp_type { IPCP_SHIM_ETH_LLC }; +enum pol_addr_auth { + FLAT_RANDOM = 0 +}; + struct dif_config { char * dif_name; enum ipcp_type type; @@ -58,6 +62,8 @@ struct dif_config { uint32_t min_pdu_size; uint32_t max_pdu_size; + + enum pol_addr_auth addr_auth_type; }; /* Shim UDP */ struct { diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c index 694db7cf..89033c26 100644 --- a/src/ipcpd/ipcp.c +++ b/src/ipcpd/ipcp.c @@ -288,6 +288,7 @@ void * ipcp_main_loop(void * o) conf.has_chk = conf_msg->has_chk; conf.min_pdu_size = conf_msg->min_pdu_size; conf.max_pdu_size = conf_msg->max_pdu_size; + conf.addr_auth_type = conf_msg->addr_auth_type; } if (conf_msg->ipcp_type == IPCP_SHIM_UDP) { conf.ip_addr = conf_msg->ip_addr; diff --git a/src/ipcpd/normal/CMakeLists.txt b/src/ipcpd/normal/CMakeLists.txt index 151721a2..08c5c691 100644 --- a/src/ipcpd/normal/CMakeLists.txt +++ b/src/ipcpd/normal/CMakeLists.txt @@ -22,8 +22,10 @@ protobuf_generate_c(FLOW_ALLOC_SRCS FLOW_ALLOC_HDRS set(SOURCE_FILES # Add source files here + addr_auth.c cdap_request.c crc32.c + flat.c fmgr.c frct.c main.c diff --git a/src/ipcpd/normal/addr_auth.c b/src/ipcpd/normal/addr_auth.c new file mode 100644 index 00000000..71bcfafa --- /dev/null +++ b/src/ipcpd/normal/addr_auth.c @@ -0,0 +1,78 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * Address authority + * + * Sander Vrijders + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define OUROBOROS_PREFIX "addr_auth" + +#include +#include + +#include "addr_auth.h" +#include "flat.h" + +#include +#include + +struct addr_auth * addr_auth_create(enum pol_addr_auth type) +{ + struct addr_auth * tmp; + + tmp = malloc(sizeof(*tmp)); + if (tmp == NULL) + return NULL; + + switch (type) { + case FLAT_RANDOM: + if (flat_init()) { + free(tmp); + return NULL; + } + + tmp->address = flat_address; + tmp->type = type; + break; + default: + LOG_ERR("Unknown address authority type."); + free(tmp); + return NULL; + } + + return tmp; +} + +int addr_auth_destroy(struct addr_auth * instance) +{ + assert(instance); + + switch (instance->type) { + case FLAT_RANDOM: + if (flat_fini()) { + return -1; + } + break; + default: + LOG_ERR("Unknown address authority type."); + } + + free(instance); + + return 0; +} diff --git a/src/ipcpd/normal/addr_auth.h b/src/ipcpd/normal/addr_auth.h new file mode 100644 index 00000000..6881dd55 --- /dev/null +++ b/src/ipcpd/normal/addr_auth.h @@ -0,0 +1,39 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * Address authority + * + * Sander Vrijders + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef OUROBOROS_ADDR_AUTH +#define OUROBOROS_ADDR_AUTH + +#include + +#include + +struct addr_auth { + enum pol_addr_auth type; + uint64_t (* address)(void); +}; + +struct addr_auth * addr_auth_create(enum pol_addr_auth type); + +int addr_auth_destroy(struct addr_auth * instance); + +#endif /* OUROBOROS_ADDR_AUTH */ diff --git a/src/ipcpd/normal/flat.c b/src/ipcpd/normal/flat.c new file mode 100644 index 00000000..8caa85b4 --- /dev/null +++ b/src/ipcpd/normal/flat.c @@ -0,0 +1,63 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * Policy for flat addresses in a distributed way + * + * Sander Vrijders + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define OUROBOROS_PREFIX "flat-addr-auth" + +#include +#include + +#include +#include +#include + +#include "shm_pci.h" +#include "ribmgr.h" + +int flat_init(void) +{ + srand(time(NULL)); + + return 0; +} + +int flat_fini(void) +{ + return 0; +} + +uint64_t flat_address(void) +{ + uint64_t addr; + uint64_t max_addr; + struct dt_const * dtc; + + dtc = ribmgr_dt_const(); + if (dtc == NULL) + return INVALID_ADDR; + + max_addr = (1 << (8 * dtc->addr_size)) - 1; + addr = (rand() % (max_addr - 1)) + 1; + + /* FIXME: Add check for uniqueness of address */ + + return addr; +} diff --git a/src/ipcpd/normal/flat.h b/src/ipcpd/normal/flat.h new file mode 100644 index 00000000..51cb511b --- /dev/null +++ b/src/ipcpd/normal/flat.h @@ -0,0 +1,30 @@ +/* + * Ouroboros - Copyright (C) 2016 + * + * Policy for flat addresses in a distributed way + * + * Sander Vrijders + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef OUROBOROS_FLAT +#define OUROBOROS_FLAT + +int flat_init(void); +int flat_fini(void); +uint64_t flat_address(void); + +#endif /* OUROBOROS_FLAT */ diff --git a/src/ipcpd/normal/ribmgr.c b/src/ipcpd/normal/ribmgr.c index cd12bcc6..295a6724 100644 --- a/src/ipcpd/normal/ribmgr.c +++ b/src/ipcpd/normal/ribmgr.c @@ -34,6 +34,7 @@ #include #include +#include "addr_auth.h" #include "ribmgr.h" #include "dt_const.h" #include "frct.h" @@ -53,15 +54,17 @@ struct mgmt_flow { }; struct { - struct dt_const dtc; + struct dt_const dtc; - uint32_t address; + uint64_t address; - struct list_head flows; - pthread_rwlock_t flows_lock; + struct list_head flows; + pthread_rwlock_t flows_lock; - struct list_head cdap_reqs; - pthread_mutex_t cdap_reqs_lock; + struct list_head cdap_reqs; + pthread_mutex_t cdap_reqs_lock; + + struct addr_auth * addr_auth; } rib; /* Call while holding cdap_reqs_lock */ @@ -153,6 +156,9 @@ int ribmgr_fini() } pthread_rwlock_unlock(&rib.flows_lock); + if (rib.addr_auth != NULL) + addr_auth_destroy(rib.addr_auth); + pthread_mutex_destroy(&rib.cdap_reqs_lock); pthread_rwlock_destroy(&rib.flows_lock); @@ -247,7 +253,18 @@ int ribmgr_cdap_write(struct cdap * instance, rib.dtc.min_pdu_size = msg->min_pdu_size; rib.dtc.max_pdu_size = msg->max_pdu_size; - rib.address = msg->address; + rib.addr_auth = addr_auth_create(msg->addr_auth_type); + if (rib.addr_auth == NULL) { + ipcp_set_state(IPCP_INIT); + pthread_rwlock_unlock(&ipcpi.state_lock); + cdap_send_reply(instance, invoke_id, -1, NULL, 0); + static_info_msg__free_unpacked(msg, NULL); + LOG_ERR("Failed to create address authority"); + return -1; + } + + rib.address = rib.addr_auth->address(); + LOG_DBG("IPCP has address %lu", rib.address); if (frct_init()) { ipcp_set_state(IPCP_INIT); @@ -333,9 +350,7 @@ int ribmgr_cdap_start(struct cdap * instance, stat_info.has_chk = rib.dtc.has_chk; stat_info.min_pdu_size = rib.dtc.min_pdu_size; stat_info.max_pdu_size = rib.dtc.max_pdu_size; - - /* FIXME: Hand out an address. */ - stat_info.address = 0; + stat_info.addr_auth_type = rib.addr_auth->type; len = static_info_msg__get_packed_size(&stat_info); if (len == 0) { @@ -544,11 +559,18 @@ int ribmgr_bootstrap(struct dif_config * conf) rib.dtc.min_pdu_size = conf->min_pdu_size; rib.dtc.max_pdu_size = conf->max_pdu_size; - /* FIXME: Set correct address. */ - rib.address = 0; + rib.addr_auth = addr_auth_create(conf->addr_auth_type); + if (rib.addr_auth == NULL) { + LOG_ERR("Failed to create address authority."); + return -1; + } + + rib.address = rib.addr_auth->address(); + LOG_DBG("IPCP has address %lu", rib.address); if (frct_init()) { LOG_ERR("Failed to initialize FRCT."); + addr_auth_destroy(rib.addr_auth); return -1; } @@ -562,7 +584,7 @@ struct dt_const * ribmgr_dt_const() return &(rib.dtc); } -uint32_t ribmgr_address() +uint64_t ribmgr_address() { return rib.address; } diff --git a/src/ipcpd/normal/ribmgr.h b/src/ipcpd/normal/ribmgr.h index 01bfcb40..556a399f 100644 --- a/src/ipcpd/normal/ribmgr.h +++ b/src/ipcpd/normal/ribmgr.h @@ -24,6 +24,7 @@ #define OUROBOROS_IPCP_RIBMGR_H #include +#include #include "dt_const.h" @@ -43,6 +44,6 @@ int ribmgr_bootstrap(struct dif_config * conf); */ struct dt_const * ribmgr_dt_const(void); -uint32_t ribmgr_address(void); +uint64_t ribmgr_address(void); #endif diff --git a/src/ipcpd/normal/shm_pci.h b/src/ipcpd/normal/shm_pci.h index 2836737c..6e955d84 100644 --- a/src/ipcpd/normal/shm_pci.h +++ b/src/ipcpd/normal/shm_pci.h @@ -34,6 +34,7 @@ typedef uint32_t cep_id_t; #define INVALID_CEP_ID 0 +#define INVALID_ADDR 0 struct pci { uint8_t pdu_type; diff --git a/src/ipcpd/normal/static_info.proto b/src/ipcpd/normal/static_info.proto index 04824a38..65a53377 100644 --- a/src/ipcpd/normal/static_info.proto +++ b/src/ipcpd/normal/static_info.proto @@ -7,5 +7,5 @@ message static_info_msg { required bool has_chk = 6; required uint32 min_pdu_size = 7; required uint32 max_pdu_size = 8; - required uint32 address = 9; + required uint32 addr_auth_type = 9; } \ No newline at end of file diff --git a/src/lib/dif_config.proto b/src/lib/dif_config.proto index 338634d1..7eff28ba 100644 --- a/src/lib/dif_config.proto +++ b/src/lib/dif_config.proto @@ -11,9 +11,10 @@ message dif_config_msg { optional bool has_chk = 9; optional uint32 min_pdu_size = 10; optional uint32 max_pdu_size = 11; + optional uint32 addr_auth_type = 12; // Config for shim UDP - optional uint32 ip_addr = 12; - optional uint32 dns_addr = 13; + optional uint32 ip_addr = 13; + optional uint32 dns_addr = 14; // Config for the shim Ethernet LLC - optional string if_name = 14; + optional string if_name = 15; } \ No newline at end of file diff --git a/src/lib/irm.c b/src/lib/irm.c index c68aa0f6..b1998145 100644 --- a/src/lib/irm.c +++ b/src/lib/irm.c @@ -119,6 +119,7 @@ int irm_bootstrap_ipcp(pid_t api, config.has_has_chk = true; config.has_min_pdu_size = true; config.has_max_pdu_size = true; + config.has_addr_auth_type = true; config.addr_size = conf->addr_size; config.cep_id_size = conf->cep_id_size; @@ -129,6 +130,7 @@ int irm_bootstrap_ipcp(pid_t api, config.has_chk = conf->has_chk; config.min_pdu_size = conf->min_pdu_size; config.max_pdu_size = conf->max_pdu_size; + config.addr_auth_type = conf->addr_auth_type; break; case IPCP_SHIM_UDP: config.has_ip_addr = true; diff --git a/src/tools/irm/irm_ipcp_bootstrap.c b/src/tools/irm/irm_ipcp_bootstrap.c index 7d72eb15..65e99765 100644 --- a/src/tools/irm/irm_ipcp_bootstrap.c +++ b/src/tools/irm/irm_ipcp_bootstrap.c @@ -45,6 +45,9 @@ #define DEFAULT_MIN_PDU_SIZE 0 #define DEFAULT_MAX_PDU_SIZE 9000 #define DEFAULT_DDNS 0 +#define DEFAULT_ADDR_AUTH FLAT_RANDOM + +#define ADDR_AUTH_FLAT "flat" static void usage(void) { @@ -64,6 +67,7 @@ static void usage(void) " [chk ]\n" " [min_pdu (default: %d)]\n" " [max_pdu (default: %d)]\n" + " [addr_auth
(default: %s)]\n" "if TYPE == " SHIM_UDP "\n" " ip \n" " [dns " @@ -72,7 +76,8 @@ static void usage(void) " if_name \n", DEFAULT_ADDR_SIZE, DEFAULT_CEP_ID_SIZE, DEFAULT_PDU_LEN_SIZE, DEFAULT_SEQ_NO_SIZE, - DEFAULT_MIN_PDU_SIZE, DEFAULT_MAX_PDU_SIZE, DEFAULT_DDNS); + DEFAULT_MIN_PDU_SIZE, DEFAULT_MAX_PDU_SIZE, + ADDR_AUTH_FLAT, DEFAULT_DDNS); } int do_bootstrap_ipcp(int argc, char ** argv) @@ -88,6 +93,7 @@ int do_bootstrap_ipcp(int argc, char ** argv) bool has_chk = false; uint32_t min_pdu_size = DEFAULT_MIN_PDU_SIZE; uint32_t max_pdu_size = DEFAULT_MAX_PDU_SIZE; + enum pol_addr_auth addr_auth_type = DEFAULT_ADDR_AUTH; uint32_t ip_addr = 0; uint32_t dns_addr = DEFAULT_DDNS; char * ipcp_type = NULL; @@ -136,6 +142,9 @@ int do_bootstrap_ipcp(int argc, char ** argv) min_pdu_size = atoi(*(argv + 1)); } else if (matches(*argv, "max_pdu") == 0) { max_pdu_size = atoi(*(argv + 1)); + } else if (matches(*argv, "addr_auth") == 0) { + if (strcmp(ADDR_AUTH_FLAT, *(argv + 1)) == 0) + addr_auth_type = FLAT_RANDOM; } else { printf("\"%s\" is unknown, try \"irm " "ipcp bootstrap\".\n", *argv); @@ -163,6 +172,7 @@ int do_bootstrap_ipcp(int argc, char ** argv) conf.has_chk = has_chk; conf.min_pdu_size = min_pdu_size; conf.max_pdu_size = max_pdu_size; + conf.addr_auth_type = addr_auth_type; } else if (strcmp(ipcp_type, SHIM_UDP) == 0) { conf.type = IPCP_SHIM_UDP; if (ip_addr == 0) { -- cgit v1.2.3