summaryrefslogtreecommitdiff
path: root/src/ipcpd/normal
diff options
context:
space:
mode:
authorSander Vrijders <[email protected]>2016-08-08 13:37:30 +0200
committerSander Vrijders <[email protected]>2016-08-08 14:33:31 +0200
commitd13a6dfd0f7a8ebc98cdb59cf0a04a282fa1593d (patch)
treeae9898536ee5767080b39e82806804fbf9911605 /src/ipcpd/normal
parent3c80fae407f451691a4a4178617986e32d0c8162 (diff)
downloadouroboros-d13a6dfd0f7a8ebc98cdb59cf0a04a282fa1593d.tar.gz
ouroboros-d13a6dfd0f7a8ebc98cdb59cf0a04a282fa1593d.zip
ipcpd: normal: Allow exchange of static DIF information
This adds the functionality of exchanging the static DIF information between 2 DIF members. After exchange the enrollment is stopped, and the IPCP that initiated enrollment transitions to the enrolled state.
Diffstat (limited to 'src/ipcpd/normal')
-rw-r--r--src/ipcpd/normal/CMakeLists.txt6
-rw-r--r--src/ipcpd/normal/fmgr.c4
-rw-r--r--src/ipcpd/normal/frct.c7
-rw-r--r--src/ipcpd/normal/frct.h3
-rw-r--r--src/ipcpd/normal/main.c9
-rw-r--r--src/ipcpd/normal/ribmgr.c235
-rw-r--r--src/ipcpd/normal/static_info.proto11
7 files changed, 248 insertions, 27 deletions
diff --git a/src/ipcpd/normal/CMakeLists.txt b/src/ipcpd/normal/CMakeLists.txt
index 7e6d9266..1e291d30 100644
--- a/src/ipcpd/normal/CMakeLists.txt
+++ b/src/ipcpd/normal/CMakeLists.txt
@@ -14,6 +14,9 @@ include_directories(${CMAKE_BINARY_DIR}/include)
SET(IPCP_NORMAL_TARGET ipcpd-normal CACHE STRING "IPCP_NORMAL_TARGET")
+protobuf_generate_c(STATIC_INFO_SRCS STATIC_INFO_HDRS
+ static_info.proto)
+
set(SOURCE_FILES
# Add source files here
main.c
@@ -22,7 +25,8 @@ set(SOURCE_FILES
ribmgr.c
)
-add_executable (ipcpd-normal ${SOURCE_FILES} ${IPCP_SOURCES})
+add_executable (ipcpd-normal ${SOURCE_FILES} ${IPCP_SOURCES}
+ ${STATIC_INFO_SRCS})
target_link_libraries (ipcpd-normal LINK_PUBLIC ouroboros)
include(MacroAddCompileFlags)
diff --git a/src/ipcpd/normal/fmgr.c b/src/ipcpd/normal/fmgr.c
index a539b289..f9de16c4 100644
--- a/src/ipcpd/normal/fmgr.c
+++ b/src/ipcpd/normal/fmgr.c
@@ -82,8 +82,8 @@ static void * fmgr_listen(void * o)
/* FIXME: Avoid busy wait and react to pthread_cond_t */
pthread_rwlock_rdlock(&_ipcp->state_lock);
- while (_ipcp->state != IPCP_ENROLLED ||
- _ipcp->state != IPCP_SHUTDOWN) {
+ while (!(_ipcp->state == IPCP_ENROLLED ||
+ _ipcp->state == IPCP_SHUTDOWN)) {
pthread_rwlock_unlock(&_ipcp->state_lock);
sched_yield();
pthread_rwlock_rdlock(&_ipcp->state_lock);
diff --git a/src/ipcpd/normal/frct.c b/src/ipcpd/normal/frct.c
index ba465540..2de9422d 100644
--- a/src/ipcpd/normal/frct.c
+++ b/src/ipcpd/normal/frct.c
@@ -33,9 +33,10 @@ struct frct_i {
struct frct {
struct dt_const * dtc;
+ uint32_t address;
} * frct = NULL;
-int frct_init(struct dt_const * dtc)
+int frct_init(struct dt_const * dtc, uint32_t address)
{
if (dtc == NULL)
return -1;
@@ -45,13 +46,15 @@ int frct_init(struct dt_const * dtc)
return -1;
frct->dtc = dtc;
+ frct->address = address;
return 0;
}
int frct_fini()
{
- free(frct);
+ if (frct != NULL)
+ free(frct);
return 0;
}
diff --git a/src/ipcpd/normal/frct.h b/src/ipcpd/normal/frct.h
index 515bed3f..2e965d38 100644
--- a/src/ipcpd/normal/frct.h
+++ b/src/ipcpd/normal/frct.h
@@ -29,7 +29,8 @@
struct frct_i;
-int frct_init(struct dt_const * dtc);
+int frct_init(struct dt_const * dtc,
+ uint32_t address);
int frct_fini();
struct frct_i * frct_i_create(int port_id,
diff --git a/src/ipcpd/normal/main.c b/src/ipcpd/normal/main.c
index 57fb72df..2d416942 100644
--- a/src/ipcpd/normal/main.c
+++ b/src/ipcpd/normal/main.c
@@ -146,7 +146,14 @@ static int normal_ipcp_enroll(char * dif_name)
return -1;
}
- /* FIXME: Wait until state changed to ENROLLED */
+ /* FIXME: Wait passively until state changed to ENROLLED */
+ pthread_rwlock_rdlock(&_ipcp->state_lock);
+ while (_ipcp->state != IPCP_ENROLLED) {
+ pthread_rwlock_unlock(&_ipcp->state_lock);
+ sched_yield();
+ pthread_rwlock_rdlock(&_ipcp->state_lock);
+ }
+ pthread_rwlock_unlock(&_ipcp->state_lock);
return 0;
}
diff --git a/src/ipcpd/normal/ribmgr.c b/src/ipcpd/normal/ribmgr.c
index 8bb320c0..2a68877a 100644
--- a/src/ipcpd/normal/ribmgr.c
+++ b/src/ipcpd/normal/ribmgr.c
@@ -36,7 +36,11 @@
#include "frct.h"
#include "ipcp.h"
-#define ENROLLMENT "enrollment"
+#include "static_info.pb-c.h"
+typedef StaticInfoMsg static_info_msg_t;
+
+#define ENROLLMENT "enrollment"
+#define STATIC_INFO "static DIF information"
extern struct ipcp * _ipcp;
@@ -67,6 +71,8 @@ struct mgmt_flow {
struct rib {
struct dt_const dtc;
+ uint32_t address;
+
struct list_head flows;
pthread_rwlock_t flows_lock;
@@ -162,17 +168,41 @@ int ribmgr_fini()
int ribmgr_cdap_reply(struct cdap * instance,
int invoke_id,
int result,
- buffer_t * val,
+ uint8_t * data,
size_t len)
{
- LOG_MISSING;
+ struct list_head * pos, * n = NULL;
- /* FIXME: Check all cdap_reqs here to see if we expect a reply */
+ pthread_mutex_lock(&rib->cdap_reqs_lock);
+ list_for_each_safe(pos, n, &rib->cdap_reqs) {
+ struct cdap_request * req =
+ list_entry(pos, struct cdap_request, next);
+ if (req->instance == instance &&
+ req->invoke_id == invoke_id) {
+ if (result != 0)
+ LOG_ERR("CDAP command with code %d and name %s "
+ "failed with error %d",
+ req->code, req->name, result);
+ else
+ LOG_DBG("CDAP command with code %d and name %s "
+ "executed succesfully",
+ req->code, req->name);
+
+ /* FIXME: In case of a read, update values here */
+
+ free(req->name);
+ list_del(&req->next);
+ free(req);
+ break;
+ }
+ }
+ pthread_mutex_unlock(&rib->cdap_reqs_lock);
- return -1;
+ return 0;
}
int ribmgr_cdap_read(struct cdap * instance,
+ int invoke_id,
char * name)
{
LOG_MISSING;
@@ -181,19 +211,67 @@ int ribmgr_cdap_read(struct cdap * instance,
}
int ribmgr_cdap_write(struct cdap * instance,
+ int invoke_id,
char * name,
- buffer_t * val,
+ uint8_t * data,
size_t len,
uint32_t flags)
{
- LOG_MISSING;
+ static_info_msg_t * msg;
+ int ret = 0;
+
+ pthread_rwlock_wrlock(&_ipcp->state_lock);
+ if (_ipcp->state == IPCP_PENDING_ENROLL &&
+ strcmp(name, STATIC_INFO) == 0) {
+ LOG_DBG("Received static DIF information.");
+
+ msg = static_info_msg__unpack(NULL, len, data);
+ if (msg == NULL) {
+ _ipcp->state = IPCP_INIT;
+ pthread_rwlock_unlock(&_ipcp->state_lock);
+ cdap_send_reply(instance, invoke_id, -1, NULL, 0);
+ LOG_ERR("Failed to unpack static info message.");
+ return -1;
+ }
- return -1;
+ rib->dtc.addr_size = msg->addr_size;
+ rib->dtc.cep_id_size = msg->cep_id_size;
+ rib->dtc.pdu_length_size = msg->pdu_length_size;
+ rib->dtc.seqno_size = msg->seqno_size;
+ rib->dtc.ttl_size = msg->ttl_size;
+ rib->dtc.chk_size = msg->chk_size;
+ rib->dtc.min_pdu_size = msg->min_pdu_size;
+ rib->dtc.max_pdu_size = msg->max_pdu_size;
+
+ rib->address = msg->address;
+
+ if (frct_init(&rib->dtc, rib->address)) {
+ _ipcp->state = IPCP_INIT;
+ pthread_rwlock_unlock(&_ipcp->state_lock);
+ cdap_send_reply(instance, invoke_id, -1, NULL, 0);
+ static_info_msg__free_unpacked(msg, NULL);
+ LOG_ERR("Failed to init FRCT");
+ return -1;
+ }
+
+ static_info_msg__free_unpacked(msg, NULL);
+ } else
+ ret = -1;
+ pthread_rwlock_unlock(&_ipcp->state_lock);
+
+ if (cdap_send_reply(instance, invoke_id, ret, NULL, 0)) {
+ LOG_ERR("Failed to send reply to write request.");
+ return -1;
+ }
+
+ return 0;
}
int ribmgr_cdap_create(struct cdap * instance,
+ int invoke_id,
char * name,
- buffer_t val)
+ uint8_t * data,
+ size_t len)
{
LOG_MISSING;
@@ -201,8 +279,10 @@ int ribmgr_cdap_create(struct cdap * instance,
}
int ribmgr_cdap_delete(struct cdap * instance,
+ int invoke_id,
char * name,
- buffer_t val)
+ uint8_t * data,
+ size_t len)
{
LOG_MISSING;
@@ -210,21 +290,135 @@ int ribmgr_cdap_delete(struct cdap * instance,
}
int ribmgr_cdap_start(struct cdap * instance,
+ int invoke_id,
char * name)
{
- LOG_MISSING;
+ static_info_msg_t stat_info = STATIC_INFO_MSG__INIT;
+ uint8_t * data = NULL;
+ size_t len = 0;
+ int iid = 0;
- /* FIXME: Handle enrollment request here */
+ pthread_rwlock_rdlock(&_ipcp->state_lock);
+ if (_ipcp->state == IPCP_ENROLLED &&
+ strcmp(name, ENROLLMENT) == 0) {
+ LOG_DBG("New enrollment request.");
- return -1;
+ if (cdap_send_reply(instance, invoke_id, 0, NULL, 0)) {
+ pthread_rwlock_unlock(&_ipcp->state_lock);
+ LOG_ERR("Failed to send reply to enrollment request.");
+ return -1;
+ }
+
+ stat_info.addr_size = rib->dtc.addr_size;
+ stat_info.cep_id_size = rib->dtc.cep_id_size;
+ stat_info.pdu_length_size = rib->dtc.pdu_length_size;
+ stat_info.seqno_size = rib->dtc.seqno_size;
+ stat_info.ttl_size = rib->dtc.ttl_size;
+ stat_info.chk_size = rib->dtc.chk_size;
+ 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;
+
+ len = static_info_msg__get_packed_size(&stat_info);
+ if (len == 0) {
+ pthread_rwlock_unlock(&_ipcp->state_lock);
+ LOG_ERR("Failed to get size of static information.");
+ return -1;
+ }
+
+ data = malloc(len);
+ if (data == NULL) {
+ pthread_rwlock_unlock(&_ipcp->state_lock);
+ LOG_ERR("Failed to allocate memory.");
+ return -1;
+ }
+
+ static_info_msg__pack(&stat_info, data);
+
+ LOG_DBGF("Sending static info...");
+
+ pthread_mutex_lock(&rib->cdap_reqs_lock);
+
+ iid = cdap_send_write(instance, STATIC_INFO, data, len, 0);
+ if (iid < 0) {
+ pthread_mutex_unlock(&rib->cdap_reqs_lock);
+ pthread_rwlock_unlock(&_ipcp->state_lock);
+ free(data);
+ LOG_ERR("Failed to send static information.");
+ return -1;
+ }
+
+ if (cdap_request_add(instance, WRITE, STATIC_INFO, iid)) {
+ pthread_mutex_unlock(&rib->cdap_reqs_lock);
+ pthread_rwlock_unlock(&_ipcp->state_lock);
+ free(data);
+ LOG_ERR("Failed to add CDAP request to list.");
+ return -1;
+ }
+ pthread_mutex_unlock(&rib->cdap_reqs_lock);
+
+ /* FIXME: Send neighbors here. */
+
+ LOG_DBGF("Sending stop enrollment...");
+
+ pthread_mutex_lock(&rib->cdap_reqs_lock);
+
+ iid = cdap_send_stop(instance, ENROLLMENT);
+ if (iid < 0) {
+ pthread_mutex_unlock(&rib->cdap_reqs_lock);
+ pthread_rwlock_unlock(&_ipcp->state_lock);
+ free(data);
+ LOG_ERR("Failed to send stop of enrollment.");
+ return -1;
+ }
+
+ if (cdap_request_add(instance, STOP, ENROLLMENT, iid)) {
+ pthread_mutex_unlock(&rib->cdap_reqs_lock);
+ pthread_rwlock_unlock(&_ipcp->state_lock);
+ free(data);
+ LOG_ERR("Failed to add CDAP request to list.");
+ return -1;
+ }
+ pthread_mutex_unlock(&rib->cdap_reqs_lock);
+
+ free(data);
+ } else {
+ if (cdap_send_reply(instance, invoke_id, -1, NULL, 0)) {
+ pthread_rwlock_unlock(&_ipcp->state_lock);
+ LOG_ERR("Failed to send reply to start request.");
+ return -1;
+ }
+ }
+ pthread_rwlock_unlock(&_ipcp->state_lock);
+
+ return 0;
}
int ribmgr_cdap_stop(struct cdap * instance,
+ int invoke_id,
char * name)
{
- LOG_MISSING;
+ int ret = 0;
- return -1;
+ pthread_rwlock_wrlock(&_ipcp->state_lock);
+ if (_ipcp->state == IPCP_PENDING_ENROLL &&
+ strcmp(name, ENROLLMENT) == 0) {
+ LOG_DBG("Stop enrollment received.");
+
+ _ipcp->state = IPCP_ENROLLED;
+ } else
+ ret = -1;
+
+ if (cdap_send_reply(instance, invoke_id, ret, NULL, 0)) {
+ pthread_rwlock_unlock(&_ipcp->state_lock);
+ LOG_ERR("Failed to send reply to stop request.");
+ return -1;
+ }
+ pthread_rwlock_unlock(&_ipcp->state_lock);
+
+ return 0;
}
static struct cdap_ops ribmgr_ops = {
@@ -258,13 +452,11 @@ int ribmgr_add_flow(int fd)
flow->instance = instance;
flow->fd = fd;
- pthread_rwlock_rdlock(&_ipcp->state_lock);
+ pthread_rwlock_wrlock(&_ipcp->state_lock);
pthread_rwlock_wrlock(&rib->flows_lock);
if (list_empty(&rib->flows) &&
- (_ipcp->state == IPCP_INIT ||
- _ipcp->state == IPCP_DISCONNECTED)) {
+ _ipcp->state == IPCP_INIT) {
_ipcp->state = IPCP_PENDING_ENROLL;
- pthread_rwlock_unlock(&_ipcp->state_lock);
pthread_mutex_lock(&rib->cdap_reqs_lock);
iid = cdap_send_start(instance,
@@ -334,7 +526,10 @@ 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;
- if (frct_init(&rib->dtc)) {
+ /* FIXME: Set correct address. */
+ rib->address = 0;
+
+ if (frct_init(&rib->dtc, rib->address)) {
LOG_ERR("Failed to initialize FRCT.");
return -1;
}
diff --git a/src/ipcpd/normal/static_info.proto b/src/ipcpd/normal/static_info.proto
new file mode 100644
index 00000000..24b7994a
--- /dev/null
+++ b/src/ipcpd/normal/static_info.proto
@@ -0,0 +1,11 @@
+message static_info_msg {
+ required uint32 addr_size = 1;
+ required uint32 cep_id_size = 2;
+ required uint32 pdu_length_size = 3;
+ required uint32 seqno_size = 4;
+ required uint32 ttl_size = 5;
+ required uint32 chk_size = 6;
+ required uint32 min_pdu_size = 7;
+ required uint32 max_pdu_size = 8;
+ required uint32 address = 9;
+} \ No newline at end of file