summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorSander Vrijders <sander.vrijders@ugent.be>2017-06-21 10:24:55 +0000
committerdimitri staessens <dimitri.staessens@ugent.be>2017-06-21 10:24:55 +0000
commit2057bd9666cbcc09e7abc92e260ba20907f6a299 (patch)
treee0bbe49e68ba86be325ee23c5879a7611df87c9f /src/lib
parent22020246ac2b6f03f42dffb48ced19e43b3e9b77 (diff)
parent806629e64e8231d0c57a80d3b6584094cd6c89bd (diff)
downloadouroboros-2057bd9666cbcc09e7abc92e260ba20907f6a299.tar.gz
ouroboros-2057bd9666cbcc09e7abc92e260ba20907f6a299.zip
Merged in sandervrijders/ouroboros/be-qos (pull request #517)
lib, ipcpd, irmd: Add full-fledged QoS
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/CMakeLists.txt5
-rw-r--r--src/lib/dev.c116
-rw-r--r--src/lib/frct_enroll.proto32
-rw-r--r--src/lib/qos.c57
-rw-r--r--src/lib/qoscube.c76
5 files changed, 253 insertions, 33 deletions
diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt
index 263065dd..99dd96fc 100644
--- a/src/lib/CMakeLists.txt
+++ b/src/lib/CMakeLists.txt
@@ -11,6 +11,7 @@ protobuf_generate_c(DIF_CONFIG_PROTO_SRCS DIF_CONFIG_PROTO_HDRS
protobuf_generate_c(CDAP_PROTO_SRCS CDAP_PROTO_HDRS cdap.proto)
protobuf_generate_c(RO_PROTO_SRCS RO_PROTO_HDRS ro.proto)
protobuf_generate_c(CACEP_PROTO_SRCS CACEP_PROTO_HDRS cacep.proto)
+protobuf_generate_c(FRCT_ENROLL_SRCS FRCT_ENROLL_HDRS frct_enroll.proto)
if (NOT APPLE)
find_library(LIBRT_LIBRARIES rt)
@@ -43,6 +44,8 @@ set(SOURCE_FILES
logs.c
md5.c
nsm.c
+ qos.c
+ qoscube.c
rib.c
sha3.c
shm_flow_set.c
@@ -55,7 +58,7 @@ set(SOURCE_FILES
add_library(ouroboros SHARED ${SOURCE_FILES} ${IRM_PROTO_SRCS}
${IPCP_PROTO_SRCS} ${DIF_CONFIG_PROTO_SRCS} ${CDAP_PROTO_SRCS}
- ${CACEP_PROTO_SRCS} ${RO_PROTO_SRCS})
+ ${CACEP_PROTO_SRCS} ${RO_PROTO_SRCS} ${FRCT_ENROLL_SRCS})
target_link_libraries(ouroboros ${LIBRT_LIBRARIES}
${LIBPTHREAD_LIBRARIES} ${PROTOBUF_C_LIBRARY})
diff --git a/src/lib/dev.c b/src/lib/dev.c
index 3cdcc4d3..e4fd32cc 100644
--- a/src/lib/dev.c
+++ b/src/lib/dev.c
@@ -34,11 +34,14 @@
#include <ouroboros/shm_rbuff.h>
#include <ouroboros/utils.h>
#include <ouroboros/fqueue.h>
+#include <ouroboros/qoscube.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
+#define BUF_SIZE 1500
+
struct flow_set {
size_t idx;
};
@@ -72,6 +75,7 @@ struct flow {
int port_id;
int oflags;
qoscube_t cube;
+ qosspec_t spec;
pid_t api;
@@ -174,24 +178,6 @@ static enum port_state port_wait_assign(int port_id)
return state;
}
-/* FIXME: translate real spec to cube */
-static qoscube_t spec_to_cube(qosspec_t * qs)
-{
- if (qs == NULL)
- return QOS_CUBE_BE;
-
- return qs->cube;
-}
-
-/* FIXME: fill real spec */
-static void fill_qosspec(qosspec_t * qs,
- qoscube_t cube)
-{
- assert(qs);
-
- qs->cube = cube;
-}
-
static int api_announce(char * ap_name)
{
irm_msg_t msg = IRM_MSG__INIT;
@@ -382,9 +368,13 @@ void ouroboros_fini()
int flow_accept(qosspec_t * qs,
const struct timespec * timeo)
{
- irm_msg_t msg = IRM_MSG__INIT;
- irm_msg_t * recv_msg = NULL;
- int fd = -1;
+ irm_msg_t msg = IRM_MSG__INIT;
+ irm_msg_t * recv_msg = NULL;
+ int fd = -1;
+ frct_enroll_msg_t * frct_enroll;
+ qosspec_t spec;
+ uint8_t data[BUF_SIZE];
+ ssize_t n;
msg.code = IRM_MSG_CODE__IRM_FLOW_ACCEPT;
msg.has_api = true;
@@ -412,7 +402,8 @@ int flow_accept(qosspec_t * qs,
return res;
}
- if (!recv_msg->has_api || !recv_msg->has_port_id) {
+ if (!recv_msg->has_api || !recv_msg->has_port_id ||
+ !recv_msg->has_qoscube) {
irm_msg__free_unpacked(recv_msg, NULL);
return -EIRMD;
}
@@ -459,8 +450,7 @@ int flow_accept(qosspec_t * qs,
assert(ai.ports[ai.flows[fd].port_id].state == PORT_INIT);
- if (qs != NULL)
- fill_qosspec(qs, ai.flows[fd].cube);
+ spec = qos_cube_to_spec(recv_msg->qoscube);
ai.ports[recv_msg->port_id].fd = fd;
ai.ports[recv_msg->port_id].state = PORT_ID_ASSIGNED;
@@ -469,6 +459,33 @@ int flow_accept(qosspec_t * qs,
irm_msg__free_unpacked(recv_msg, NULL);
+ n = flow_read(fd, data, BUF_SIZE);
+ if (n < 0) {
+ flow_dealloc(fd);
+ return n;
+ }
+
+ frct_enroll = frct_enroll_msg__unpack(NULL, n, data);
+ if (frct_enroll == NULL) {
+ flow_dealloc(fd);
+ return -1;
+ }
+
+ spec.resource_control = frct_enroll->resource_control;
+ spec.reliable = frct_enroll->reliable;
+ spec.error_check = frct_enroll->error_check;
+ spec.ordered = frct_enroll->ordered;
+ spec.partial = frct_enroll->partial;
+
+ frct_enroll_msg__free_unpacked(frct_enroll, NULL);
+
+ pthread_rwlock_wrlock(&ai.flows_lock);
+ ai.flows[fd].spec = spec;
+ pthread_rwlock_unlock(&ai.flows_lock);
+
+ if (qs != NULL)
+ *qs = spec;
+
return fd;
}
@@ -476,18 +493,33 @@ int flow_alloc(const char * dst_name,
qosspec_t * qs,
const struct timespec * timeo)
{
- irm_msg_t msg = IRM_MSG__INIT;
- irm_msg_t * recv_msg = NULL;
-
- int fd;
+ irm_msg_t msg = IRM_MSG__INIT;
+ frct_enroll_msg_t frct_enroll = FRCT_ENROLL_MSG__INIT;
+ irm_msg_t * recv_msg = NULL;
+ qoscube_t qc = QOS_CUBE_BE;
+ int fd;
+ ssize_t len;
+ uint8_t * data;
+ int ret;
msg.code = IRM_MSG_CODE__IRM_FLOW_ALLOC;
msg.dst_name = (char *) dst_name;
msg.has_api = true;
msg.has_qoscube = true;
- msg.qoscube = spec_to_cube(qs);
msg.api = ai.api;
+ if (qs != NULL) {
+ frct_enroll.resource_control = qs->resource_control;
+ frct_enroll.reliable = qs->reliable;
+ frct_enroll.error_check = qs->error_check;
+ frct_enroll.ordered = qs->ordered;
+ frct_enroll.partial = qs->partial;
+
+ qc = qos_spec_to_cube(*qs);
+ }
+
+ msg.qoscube = qc;
+
if (timeo != NULL) {
msg.has_timeo_sec = true;
msg.has_timeo_nsec = true;
@@ -560,9 +592,29 @@ int flow_alloc(const char * dst_name,
ai.ports[recv_msg->port_id].fd = fd;
ai.ports[recv_msg->port_id].state = PORT_ID_ASSIGNED;
+ irm_msg__free_unpacked(recv_msg, NULL);
+
pthread_rwlock_unlock(&ai.flows_lock);
- irm_msg__free_unpacked(recv_msg, NULL);
+ len = frct_enroll_msg__get_packed_size(&frct_enroll);
+ if (len < 0) {
+ flow_dealloc(fd);
+ return -1;
+ }
+
+ data = malloc(len);
+ if (data == NULL) {
+ flow_dealloc(fd);
+ return -ENOMEM;
+ }
+
+ frct_enroll_msg__pack(&frct_enroll, data);
+
+ ret = flow_write(fd, data, len);
+ if (ret < 0) {
+ flow_dealloc(fd);
+ return ret;
+ }
return fd;
}
@@ -582,7 +634,7 @@ int flow_dealloc(int fd)
pthread_rwlock_rdlock(&ai.flows_lock);
- assert (!(ai.flows[fd].port_id < 0));
+ assert(!(ai.flows[fd].port_id < 0));
msg.port_id = ai.flows[fd].port_id;
@@ -722,7 +774,7 @@ int flow_get_qosspec(int fd,
return -ENOTALLOC;
}
- fill_qosspec(qs, ai.flows[fd].cube);
+ *qs = ai.flows[fd].spec;
pthread_rwlock_unlock(&ai.flows_lock);
diff --git a/src/lib/frct_enroll.proto b/src/lib/frct_enroll.proto
new file mode 100644
index 00000000..497d6acc
--- /dev/null
+++ b/src/lib/frct_enroll.proto
@@ -0,0 +1,32 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2017
+ *
+ * QoS messages
+ *
+ * Dimitri Staessens <dimitri.staessens@intec.ugent.be>
+ * Sander Vrijders <sander.vrijders@intec.ugent.be>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+syntax = "proto2";
+
+message frct_enroll_msg {
+ required bool resource_control = 1;
+ required bool reliable = 2;
+ required bool error_check = 3;
+ required bool ordered = 4;
+ required bool partial = 5;
+};
diff --git a/src/lib/qos.c b/src/lib/qos.c
new file mode 100644
index 00000000..035b9049
--- /dev/null
+++ b/src/lib/qos.c
@@ -0,0 +1,57 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2017
+ *
+ * Quality of Service cube specifications
+ *
+ * Dimitri Staessens <dimitri.staessens@ugent.be>
+ * Sander Vrijders <sander.vrijders@ugent.be>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <ouroboros/qos.h>
+#include <ouroboros/errno.h>
+
+#include <stdint.h>
+#include <stddef.h>
+
+int qosspec_init(qosspec_t * qs)
+{
+ if (qs == NULL)
+ return -EINVAL;
+
+ qs->delay = UINT32_MAX;
+ qs->bandwidth = UINT64_MAX;
+ qs->availability = 0;
+ qs->maximum_interruption = UINT32_MAX;
+
+ qs->resource_control = true;
+ qs->reliable = false;
+ qs->error_check = true;
+ qs->ordered = true;
+ qs->partial = false;
+
+ return 0;
+}
+
+int qosspec_fini(qosspec_t * qs)
+{
+ if (qs == NULL)
+ return -EINVAL;
+
+ qs = NULL;
+
+ return 0;
+}
diff --git a/src/lib/qoscube.c b/src/lib/qoscube.c
new file mode 100644
index 00000000..4ab827a6
--- /dev/null
+++ b/src/lib/qoscube.c
@@ -0,0 +1,76 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2017
+ *
+ * Quality of Service cube
+ *
+ * Dimitri Staessens <dimitri.staessens@ugent.be>
+ * Sander Vrijders <sander.vrijders@ugent.be>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <ouroboros/qoscube.h>
+
+#include <string.h>
+
+static struct qos_spec qos_best_effort = {
+ .delay = UINT32_MAX,
+ .bandwidth = UINT64_MAX,
+ .availability = 0,
+ .maximum_interruption = UINT32_MAX
+};
+
+static struct qos_spec qos_video = {
+ .delay = 100,
+ .bandwidth = UINT64_MAX,
+ .availability = 3,
+ .maximum_interruption = 100
+};
+
+static struct qos_spec qos_voice = {
+ .delay = 10,
+ .bandwidth = 100000,
+ .availability = 5,
+ .maximum_interruption = 50
+};
+
+qoscube_t qos_spec_to_cube(qosspec_t qs)
+{
+ if (qs.delay <= qos_voice.delay &&
+ qs.bandwidth <= qos_voice.bandwidth &&
+ qs.availability >= qos_voice.availability &&
+ qs.maximum_interruption <= qos_voice.maximum_interruption)
+ return QOS_CUBE_VOICE;
+ else if (qs.delay <= qos_video.delay &&
+ qs.bandwidth <= qos_video.bandwidth &&
+ qs.availability >= qos_video.availability &&
+ qs.maximum_interruption <= qos_video.maximum_interruption)
+ return QOS_CUBE_VIDEO;
+ else
+ return QOS_CUBE_BE;
+}
+
+qosspec_t qos_cube_to_spec(qoscube_t qc)
+{
+ switch (qc) {
+ case QOS_CUBE_VOICE:
+ return qos_voice;
+ case QOS_CUBE_VIDEO:
+ return qos_video;
+ case QOS_CUBE_BE:
+ default:
+ return qos_best_effort;
+ }
+}