summaryrefslogtreecommitdiff
path: root/src/ipcpd
diff options
context:
space:
mode:
Diffstat (limited to 'src/ipcpd')
-rw-r--r--src/ipcpd/ipcp.c1
-rw-r--r--src/ipcpd/normal/CMakeLists.txt1
-rw-r--r--src/ipcpd/normal/fmgr.c4
-rw-r--r--src/ipcpd/normal/gam.c136
-rw-r--r--src/ipcpd/normal/gam.h8
-rw-r--r--src/ipcpd/normal/pol-gam-ops.h40
-rw-r--r--src/ipcpd/normal/pol/complete.c208
-rw-r--r--src/ipcpd/normal/pol/complete.h46
-rw-r--r--src/ipcpd/normal/ribmgr.c13
-rw-r--r--src/ipcpd/normal/ribmgr.h2
-rw-r--r--src/ipcpd/normal/static_info.proto19
11 files changed, 367 insertions, 111 deletions
diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c
index 96f00dc0..a94e268d 100644
--- a/src/ipcpd/ipcp.c
+++ b/src/ipcpd/ipcp.c
@@ -128,6 +128,7 @@ static void * ipcp_main_loop(void * o)
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;
+ conf.dt_gam_type = conf_msg->dt_gam_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 43059c3e..157baa9e 100644
--- a/src/ipcpd/normal/CMakeLists.txt
+++ b/src/ipcpd/normal/CMakeLists.txt
@@ -36,6 +36,7 @@ set(SOURCE_FILES
ribmgr.c
shm_pci.c
# Add policies last
+ pol/complete.c
pol/flat.c
)
diff --git a/src/ipcpd/normal/fmgr.c b/src/ipcpd/normal/fmgr.c
index 33ac83c9..6fe6fb60 100644
--- a/src/ipcpd/normal/fmgr.c
+++ b/src/ipcpd/normal/fmgr.c
@@ -305,7 +305,7 @@ int fmgr_init()
}
}
- fmgr.gam = gam_create(DT_AE);
+ fmgr.gam = gam_create(ribmgr_dt_gam(), DT_AE);
if (fmgr.gam == NULL) {
LOG_ERR("Failed to create graph adjacency manager.");
fmgr_destroy_flows();
@@ -617,7 +617,7 @@ int fmgr_nm1_flow_arr(int fd,
assert(fmgr.gam);
if (gam_flow_arr(fmgr.gam, fd, qs)) {
- LOG_ERR("Failed to hand to connectivy manager.");
+ LOG_ERR("Failed to hand to graph adjacency manager.");
return -1;
}
diff --git a/src/ipcpd/normal/gam.c b/src/ipcpd/normal/gam.c
index 34db87e3..0e626115 100644
--- a/src/ipcpd/normal/gam.c
+++ b/src/ipcpd/normal/gam.c
@@ -3,7 +3,7 @@
*
* Graph adjacency manager for IPC Process components
*
- * Dimitri Staeesens <dimitri.staessens@intec.ugent.be>
+ * Dimitri Staessens <dimitri.staessens@intec.ugent.be>
* Sander Vrijders <sander.vrijders@intec.ugent.be>
*
* This program is free software; you can redistribute it and/or modify
@@ -25,23 +25,20 @@
#include <ouroboros/config.h>
#include <ouroboros/dev.h>
#include <ouroboros/logs.h>
-#include <ouroboros/cacep.h>
#include <ouroboros/list.h>
#include <ouroboros/errno.h>
#include "ribmgr.h"
#include "ipcp.h"
-#include "ro.h"
-#include "pathname.h"
#include "gam.h"
+#include "pol-gam-ops.h"
+#include "pol/complete.h"
#include <assert.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
-#define RO_DIR "neighbors"
-
struct ga {
struct list_head next;
@@ -51,59 +48,34 @@ struct ga {
};
struct gam {
- struct list_head gas;
- pthread_mutex_t gas_lock;
- pthread_cond_t gas_cond;
-
- char * ae_name;
+ struct list_head gas;
+ pthread_mutex_t gas_lock;
+ pthread_cond_t gas_cond;
- /* FIXME: Keep a list of known members */
+ char * ae_name;
- pthread_t allocator;
+ struct pol_gam_ops * ops;
+ void * ops_o;
};
-static void * allocator(void * o)
+struct gam * gam_create(enum pol_gam gam_type,
+ const char * ae_name)
{
- qosspec_t qs;
- ssize_t len;
- char ** children;
- struct gam * instance;
- int i;
- char * ro_name;
-
- instance = (struct gam *) o;
-
- qs.delay = 0;
- qs.jitter = 0;
-
- ro_name = pathname_create(RO_DIR);
- if (ro_name == NULL)
- return (void *) -1;
-
- len = ro_children(ro_name, &children);
- if (len > 0) {
- for (i = 0; i < len; i++) {
- if (strcmp(children[i], ipcpi.name) == 0)
- continue;
- gam_flow_alloc(instance, children[i], qs);
- }
- }
-
- pathname_destroy(ro_name);
-
- return (void *) 0;
-}
-
-struct gam * gam_create(char * ae_name)
-{
- struct gam * tmp;
- struct ro_attr attr;
- char * ro_name;
+ struct gam * tmp;
tmp = malloc(sizeof(*tmp));
if (tmp == NULL)
return NULL;
+ switch (gam_type) {
+ case COMPLETE:
+ tmp->ops = &complete_ops;
+ break;
+ default:
+ free(tmp);
+ return NULL;
+ }
+
list_head_init(&tmp->gas);
tmp->ae_name = strdup(ae_name);
@@ -125,47 +97,8 @@ struct gam * gam_create(char * ae_name)
return NULL;
}
- ro_attr_init(&attr);
- attr.enrol_sync = true;
- attr.recv_set = ALL_MEMBERS;
-
- ro_name = pathname_create(RO_DIR);
- if (ro_name == NULL) {
- pthread_mutex_destroy(&tmp->gas_lock);
- free(tmp->ae_name);
- free(tmp);
- return NULL;
- }
-
- if (!ro_exists(RO_DIR)) {
- if (ro_create(ro_name, &attr, NULL, 0)) {
- pathname_destroy(ro_name);
- pthread_mutex_destroy(&tmp->gas_lock);
- free(tmp->ae_name);
- free(tmp);
- return NULL;
- }
- }
-
- ro_name = pathname_append(ro_name, ipcpi.name);
- if (ro_name == NULL) {
- pathname_destroy(ro_name);
- pthread_mutex_destroy(&tmp->gas_lock);
- free(tmp->ae_name);
- free(tmp);
- return NULL;
- }
-
- if (ro_create(ro_name, &attr, NULL, 0)) {
- pathname_destroy(ro_name);
- pthread_mutex_destroy(&tmp->gas_lock);
- free(tmp->ae_name);
- free(tmp);
- return NULL;
- }
- pathname_destroy(ro_name);
-
- if (pthread_create(&tmp->allocator, NULL, allocator, (void *) tmp)) {
+ tmp->ops_o = tmp->ops->create(tmp);
+ if (tmp->ops_o == NULL) {
pthread_cond_destroy(&tmp->gas_cond);
pthread_mutex_destroy(&tmp->gas_lock);
free(tmp->ae_name);
@@ -183,8 +116,7 @@ void gam_destroy(struct gam * instance)
assert(instance);
- pthread_cancel(instance->allocator);
- pthread_join(instance->allocator, NULL);
+ instance->ops->destroy(instance->ops_o);
pthread_mutex_destroy(&instance->gas_lock);
pthread_cond_destroy(&instance->gas_cond);
@@ -232,7 +164,8 @@ int gam_flow_arr(struct gam * instance,
struct cacep * cacep;
struct cacep_info * info;
- if (flow_alloc_resp(fd, 0) < 0) {
+ if (flow_alloc_resp(fd, instance->ops->accept_new_flow(instance->ops_o))
+ < 0) {
LOG_ERR("Could not respond to new flow.");
return -1;
}
@@ -249,8 +182,15 @@ int gam_flow_arr(struct gam * instance,
cacep_destroy(cacep);
return -1;
}
+
cacep_destroy(cacep);
+ if (instance->ops->accept_flow(instance->ops_o, qs, info)) {
+ flow_dealloc(fd);
+ free(info);
+ return 0;
+ }
+
if (add_ga(instance, fd, qs, info)) {
LOG_ERR("Failed to add ga to graph adjacency manager list.");
free(info);
@@ -292,10 +232,17 @@ int gam_flow_alloc(struct gam * instance,
cacep_destroy(cacep);
return -1;
}
+
cacep_destroy(cacep);
+ if (instance->ops->accept_flow(instance->ops_o, qs, info)) {
+ flow_dealloc(fd);
+ free(info);
+ return 0;
+ }
+
if (add_ga(instance, fd, qs, info)) {
- LOG_ERR("Failed to add ga to graph adjacency manager list.");
+ LOG_ERR("Failed to add GA to graph adjacency manager list.");
free(info);
return -1;
}
@@ -322,7 +269,6 @@ int gam_flow_wait(struct gam * instance,
ga = list_first_entry((&instance->gas), struct ga, next);
if (ga == NULL) {
pthread_mutex_unlock(&instance->gas_lock);
- LOG_ERR("Ga was NULL.");
return -1;
}
diff --git a/src/ipcpd/normal/gam.h b/src/ipcpd/normal/gam.h
index 309cb46d..e858114c 100644
--- a/src/ipcpd/normal/gam.h
+++ b/src/ipcpd/normal/gam.h
@@ -23,8 +23,10 @@
#ifndef OUROBOROS_IPCPD_NORMAL_GAM_H
#define OUROBOROS_IPCPD_NORMAL_GAM_H
-/* FIXME: Will take a policy */
-struct gam * gam_create(char * ae_name);
+#include <ouroboros/cacep.h>
+
+struct gam * gam_create(enum pol_gam gam_type,
+ const char * ae_name);
void gam_destroy(struct gam * instance);
@@ -41,4 +43,4 @@ int gam_flow_wait(struct gam * instance,
struct cacep_info ** info,
qosspec_t * qs);
-#endif
+#endif /* OUROBOROS_IPCPD_NORMAL_GAM_H */
diff --git a/src/ipcpd/normal/pol-gam-ops.h b/src/ipcpd/normal/pol-gam-ops.h
new file mode 100644
index 00000000..eeece8d9
--- /dev/null
+++ b/src/ipcpd/normal/pol-gam-ops.h
@@ -0,0 +1,40 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2017
+ *
+ * Graph adjacency manager policy ops
+ *
+ * Dimitri Staessens <dimitri.staessens@intec.ugent.be>
+ * Sander Vrijders <sander.vrijders@intec.ugent.be>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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_IPCPD_NORMAL_POL_GAM_OPS_H
+#define OUROBOROS_IPCPD_NORMAL_POL_GAM_OPS_H
+
+#include <ouroboros/cacep.h>
+
+struct pol_gam_ops {
+ void * (* create)(struct gam * instance);
+
+ void (* destroy)(void * o);
+
+ int (* accept_new_flow)(void * o);
+
+ int (* accept_flow)(void * o,
+ qosspec_t qs,
+ const struct cacep_info * info);
+};
+
+#endif /* OUROBOROS_IPCPD_NORMAL_POL_GAM_OPS_H */
diff --git a/src/ipcpd/normal/pol/complete.c b/src/ipcpd/normal/pol/complete.c
new file mode 100644
index 00000000..89e1b91f
--- /dev/null
+++ b/src/ipcpd/normal/pol/complete.c
@@ -0,0 +1,208 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2017
+ *
+ * Graph adjacency manager for IPC Process components
+ *
+ * Dimitri Staessens <dimitri.staessens@intec.ugent.be>
+ * Sander Vrijders <sander.vrijders@intec.ugent.be>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 "complete-graph-adjacency-manager"
+
+#include <ouroboros/config.h>
+#include <ouroboros/logs.h>
+#include <ouroboros/list.h>
+#include <ouroboros/qos.h>
+
+#include "pathname.h"
+#include "ro.h"
+#include "ipcp.h"
+#include "gam.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+#define RO_DIR "neighbors"
+
+struct neighbor {
+ struct list_head next;
+ char * neighbor;
+};
+
+struct complete {
+ struct list_head neighbors;
+ pthread_mutex_t neighbors_lock;
+
+ pthread_t allocator;
+
+ struct gam * gam;
+};
+
+static void * allocator(void * o)
+{
+ qosspec_t qs;
+ ssize_t len;
+ char ** children;
+ int i;
+ char * ro_name;
+ struct complete * complete = (struct complete *) o;
+
+ qs.delay = 0;
+ qs.jitter = 0;
+
+ ro_name = pathname_create(RO_DIR);
+ if (ro_name == NULL)
+ return (void *) -1;
+
+ len = ro_children(ro_name, &children);
+ if (len > 0) {
+ for (i = 0; i < len; i++) {
+ if (strcmp(children[i], ipcpi.name) == 0)
+ continue;
+ gam_flow_alloc(complete->gam, children[i], qs);
+ }
+ }
+
+ pathname_destroy(ro_name);
+
+ return (void *) 0;
+}
+
+void * complete_create(struct gam * gam)
+{
+ struct ro_attr attr;
+ char * ro_name;
+ struct complete * complete;
+
+ ro_attr_init(&attr);
+ attr.enrol_sync = true;
+ attr.recv_set = ALL_MEMBERS;
+
+ complete = malloc(sizeof(*complete));
+ if (complete == NULL)
+ return NULL;
+
+ ro_name = pathname_create(RO_DIR);
+ if (ro_name == NULL) {
+ free(complete);
+ return NULL;
+ }
+
+ if (!ro_exists(RO_DIR)) {
+ if (ro_create(ro_name, &attr, NULL, 0)) {
+ free(complete);
+ pathname_destroy(ro_name);
+ return NULL;
+ }
+ }
+
+ ro_name = pathname_append(ro_name, ipcpi.name);
+ if (ro_name == NULL) {
+ free(complete);
+ pathname_destroy(ro_name);
+ return NULL;
+ }
+
+ if (ro_create(ro_name, &attr, NULL, 0)) {
+ free(complete);
+ pathname_destroy(ro_name);
+ return NULL;
+ }
+ pathname_destroy(ro_name);
+
+ list_head_init(&complete->neighbors);
+ complete->gam = gam;
+
+ if (pthread_mutex_init(&complete->neighbors_lock, NULL)) {
+ free(complete);
+ return NULL;
+ }
+
+ if (pthread_create(&complete->allocator, NULL,
+ allocator, (void *) complete)) {
+ free(complete);
+ pthread_mutex_destroy(&complete->neighbors_lock);
+ return NULL;
+ }
+
+ return (void *) complete;
+}
+
+void complete_destroy(void * o)
+{
+ struct list_head * p = NULL;
+ struct list_head * n = NULL;
+ struct complete * complete = (struct complete *) o;
+
+ pthread_cancel(complete->allocator);
+ pthread_join(complete->allocator, NULL);
+
+ list_for_each_safe(p, n, &complete->neighbors) {
+ struct neighbor * e = list_entry(p, struct neighbor, next);
+ list_del(&e->next);
+ free(e->neighbor);
+ free(e);
+ }
+}
+
+int complete_accept_new_flow(void * o)
+{
+ (void) o;
+
+ return 0;
+}
+
+int complete_accept_flow(void * o,
+ qosspec_t qs,
+ const struct cacep_info * info)
+{
+ struct list_head * pos = NULL;
+ struct neighbor * n;
+ struct complete * complete = (struct complete *) o;
+
+ (void) qs;
+
+ pthread_mutex_lock(&complete->neighbors_lock);
+
+ list_for_each(pos, &complete->neighbors) {
+ struct neighbor * e = list_entry(pos, struct neighbor, next);
+ if (strcmp(e->neighbor, info->name) == 0) {
+ pthread_mutex_unlock(&complete->neighbors_lock);
+ return -1;
+ }
+ }
+
+ n = malloc(sizeof(*n));
+ if (n == NULL) {
+ pthread_mutex_unlock(&complete->neighbors_lock);
+ return -1;
+ }
+
+ list_head_init(&n->next);
+
+ n->neighbor = strdup(info->name);
+ if (n->neighbor == NULL) {
+ pthread_mutex_unlock(&complete->neighbors_lock);
+ free(n);
+ return -1;
+ }
+
+ list_add(&n->next, &complete->neighbors);
+
+ pthread_mutex_unlock(&complete->neighbors_lock);
+
+ return 0;
+}
diff --git a/src/ipcpd/normal/pol/complete.h b/src/ipcpd/normal/pol/complete.h
new file mode 100644
index 00000000..8fcc87ba
--- /dev/null
+++ b/src/ipcpd/normal/pol/complete.h
@@ -0,0 +1,46 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2017
+ *
+ * Graph adjacency manager for IPC Process components
+ *
+ * Dimitri Staessens <dimitri.staessens@intec.ugent.be>
+ * Sander Vrijders <sander.vrijders@intec.ugent.be>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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_IPCPD_NORMAL_POL_COMPLETE_H
+#define OUROBOROS_IPCPD_NORMAL_POL_COMPLETE_H
+
+#include "gam.h"
+#include "pol-gam-ops.h"
+
+void * complete_create(struct gam * instance);
+
+void complete_destroy(void * o);
+
+int complete_accept_new_flow(void * o);
+
+int complete_accept_flow(void * o,
+ qosspec_t qs,
+ const struct cacep_info * info);
+
+struct pol_gam_ops complete_ops = {
+ .create = complete_create,
+ .destroy = complete_destroy,
+ .accept_new_flow = complete_accept_new_flow,
+ .accept_flow = complete_accept_flow
+};
+
+#endif /* OUROBOROS_IPCPD_NORMAL_POL_COMPLETE_H */
diff --git a/src/ipcpd/normal/ribmgr.c b/src/ipcpd/normal/ribmgr.c
index c780bf50..993fe62a 100644
--- a/src/ipcpd/normal/ribmgr.c
+++ b/src/ipcpd/normal/ribmgr.c
@@ -139,6 +139,8 @@ struct {
struct addr_auth * addr_auth;
enum pol_addr_auth addr_auth_type;
+ enum pol_gam dt_gam_type;
+
enum ribmgr_state state;
pthread_cond_t state_cond;
pthread_mutex_t state_lock;
@@ -168,6 +170,7 @@ void ribmgr_ro_created(const char * name,
rib.dtc.min_pdu_size = stat_msg->min_pdu_size;
rib.dtc.max_pdu_size = stat_msg->max_pdu_size;
rib.addr_auth_type = stat_msg->addr_auth_type;
+ rib.dt_gam_type = stat_msg->dt_gam_type;
static_info_msg__free_unpacked(stat_msg, NULL);
}
@@ -1262,6 +1265,7 @@ int ribmgr_bootstrap(struct dif_config * conf)
stat_info.min_pdu_size = rib.dtc.min_pdu_size = conf->min_pdu_size;
stat_info.max_pdu_size = rib.dtc.max_pdu_size = conf->max_pdu_size;
stat_info.addr_auth_type = rib.addr_auth_type = conf->addr_auth_type;
+ stat_info.dt_gam_type = rib.dt_gam_type = conf->dt_gam_type;
len = static_info_msg__get_packed_size(&stat_info);
if (len == 0) {
@@ -1354,16 +1358,21 @@ int ribmgr_start_policies(void)
return 0;
}
-struct dt_const * ribmgr_dt_const()
+struct dt_const * ribmgr_dt_const(void)
{
return &(rib.dtc);
}
-uint64_t ribmgr_address()
+uint64_t ribmgr_address(void)
{
return rib.address;
}
+enum pol_gam ribmgr_dt_gam(void)
+{
+ return rib.dt_gam_type;
+}
+
static int send_neighbors_ro(char * name, ro_msg_t * msg, enum cdap_opcode code)
{
struct list_head * p = NULL;
diff --git a/src/ipcpd/normal/ribmgr.h b/src/ipcpd/normal/ribmgr.h
index ddc98e6e..22212de9 100644
--- a/src/ipcpd/normal/ribmgr.h
+++ b/src/ipcpd/normal/ribmgr.h
@@ -45,4 +45,6 @@ struct dt_const * ribmgr_dt_const(void);
uint64_t ribmgr_address(void);
+enum pol_gam ribmgr_dt_gam(void);
+
#endif /* OUROBOROS_IPCPD_NORMAL_RIBMGR_H */
diff --git a/src/ipcpd/normal/static_info.proto b/src/ipcpd/normal/static_info.proto
index 18f02e36..bb6f8c4e 100644
--- a/src/ipcpd/normal/static_info.proto
+++ b/src/ipcpd/normal/static_info.proto
@@ -23,13 +23,14 @@
syntax = "proto2";
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 bool has_ttl = 5;
- required bool has_chk = 6;
- required uint32 min_pdu_size = 7;
- required uint32 max_pdu_size = 8;
- required uint32 addr_auth_type = 9;
+ required uint32 addr_size = 1;
+ required uint32 cep_id_size = 2;
+ required uint32 pdu_length_size = 3;
+ required uint32 seqno_size = 4;
+ required bool has_ttl = 5;
+ required bool has_chk = 6;
+ required uint32 min_pdu_size = 7;
+ required uint32 max_pdu_size = 8;
+ required uint32 addr_auth_type = 9;
+ required uint32 dt_gam_type = 10;
} \ No newline at end of file