From f9bd3b31c8152b037bf1dbc3409a017d57d4a2e6 Mon Sep 17 00:00:00 2001
From: Dimitri Staessens <dimitri.staessens@ugent.be>
Date: Tue, 5 Jun 2018 14:42:49 +0200
Subject: lib: Add a QOS_RAW QoS cube

This adds a QoS cube that allows sending packets directly over a raw
flow, without an FRCT state machine. Flow allocation with a NULL
qosspec will now default to such raw flows.

Signed-off-by: Dimitri Staessens <dimitri.staessens@ugent.be>
Signed-off-by: Sander Vrijders <sander.vrijders@ugent.be>
---
 include/ouroboros/qos.h     |  1 +
 include/ouroboros/qoscube.h |  3 ++-
 src/lib/dev.c               | 30 ++++++++++++++++++------------
 src/lib/qoscube.c           | 18 ++++++++++++++++--
 4 files changed, 37 insertions(+), 15 deletions(-)

diff --git a/include/ouroboros/qos.h b/include/ouroboros/qos.h
index f046f8f8..0a9bc060 100644
--- a/include/ouroboros/qos.h
+++ b/include/ouroboros/qos.h
@@ -30,6 +30,7 @@ typedef struct qos_spec {
         uint32_t delay;                /* In ms */
         uint64_t bandwidth;            /* In bits/s */
         uint8_t  availability;         /* Class of 9s */
+        uint8_t  in_order;             /* In-order delivery, enables FRCT */
         uint32_t maximum_interruption; /* In ms */
 } qosspec_t;
 
diff --git a/include/ouroboros/qoscube.h b/include/ouroboros/qoscube.h
index bce9b361..99563a06 100644
--- a/include/ouroboros/qoscube.h
+++ b/include/ouroboros/qoscube.h
@@ -26,7 +26,8 @@
 #include <ouroboros/qos.h>
 
 typedef enum qos_cube {
-        QOS_CUBE_BE = 0,
+        QOS_CUBE_RAW = 0,
+        QOS_CUBE_BE,
         QOS_CUBE_VIDEO,
         QOS_CUBE_VOICE,
         QOS_CUBE_MAX
diff --git a/src/lib/dev.c b/src/lib/dev.c
index 4a1c6688..ee82bbaa 100644
--- a/src/lib/dev.c
+++ b/src/lib/dev.c
@@ -486,6 +486,7 @@ int flow_accept(qosspec_t *             qs,
         irm_msg_t   msg = IRM_MSG__INIT;
         irm_msg_t * recv_msg;
         int         fd;
+        qoscube_t   qc;
 
         msg.code    = IRM_MSG_CODE__IRM_FLOW_ACCEPT;
         msg.has_pid = true;
@@ -519,6 +520,8 @@ int flow_accept(qosspec_t *             qs,
                 return -EIRMD;
         }
 
+        qc = recv_msg->qoscube;
+
         fd = flow_init(recv_msg->port_id, recv_msg->pid, recv_msg->qoscube);
 
         irm_msg__free_unpacked(recv_msg, NULL);
@@ -532,11 +535,13 @@ int flow_accept(qosspec_t *             qs,
 
         assert(ai.flows[fd].frcti == NULL);
 
-        ai.flows[fd].frcti = frcti_create(fd);
-        if (ai.flows[fd].frcti == NULL) {
-                flow_fini(fd);
-                pthread_rwlock_unlock(&ai.lock);
-                return -ENOMEM;
+        if (qc != QOS_CUBE_RAW) {
+                ai.flows[fd].frcti = frcti_create(fd);
+                if (ai.flows[fd].frcti == NULL) {
+                        flow_fini(fd);
+                        pthread_rwlock_unlock(&ai.lock);
+                        return -ENOMEM;
+                }
         }
 
         if (qs != NULL)
@@ -553,7 +558,7 @@ int flow_alloc(const char *            dst,
 {
         irm_msg_t   msg      = IRM_MSG__INIT;
         irm_msg_t * recv_msg;
-        qoscube_t   qc       = QOS_CUBE_BE;
+        qoscube_t   qc       = QOS_CUBE_RAW;
         int         fd;
 
         msg.code        = IRM_MSG_CODE__IRM_FLOW_ALLOC;
@@ -603,14 +608,15 @@ int flow_alloc(const char *            dst,
 
         pthread_rwlock_wrlock(&ai.lock);
 
-        /* FIXME: check if FRCT is needed based on qc? */
         assert(ai.flows[fd].frcti == NULL);
 
-        ai.flows[fd].frcti = frcti_create(fd);
-        if (ai.flows[fd].frcti == NULL) {
-                flow_fini(fd);
-                pthread_rwlock_unlock(&ai.lock);
-                return -ENOMEM;
+        if (qc != QOS_CUBE_RAW) {
+                ai.flows[fd].frcti = frcti_create(fd);
+                if (ai.flows[fd].frcti == NULL) {
+                        flow_fini(fd);
+                        pthread_rwlock_unlock(&ai.lock);
+                        return -ENOMEM;
+                }
         }
 
         pthread_rwlock_unlock(&ai.lock);
diff --git a/src/lib/qoscube.c b/src/lib/qoscube.c
index 8e6a8df9..00210625 100644
--- a/src/lib/qoscube.c
+++ b/src/lib/qoscube.c
@@ -24,10 +24,19 @@
 
 #include <string.h>
 
+static struct qos_spec qos_raw = {
+        .delay                = UINT32_MAX,
+        .bandwidth            = UINT64_MAX,
+        .availability         = 0,
+        .in_order             = 0,
+        .maximum_interruption = UINT32_MAX
+};
+
 static struct qos_spec qos_best_effort = {
         .delay                = UINT32_MAX,
         .bandwidth            = UINT64_MAX,
         .availability         = 0,
+        .in_order             = 1,
         .maximum_interruption = UINT32_MAX
 };
 
@@ -35,6 +44,7 @@ static struct qos_spec qos_video = {
         .delay                = 100,
         .bandwidth            = UINT64_MAX,
         .availability         = 3,
+        .in_order             = 1,
         .maximum_interruption = 100
 };
 
@@ -42,6 +52,7 @@ static struct qos_spec qos_voice = {
         .delay                = 10,
         .bandwidth            = 100000,
         .availability         = 5,
+        .in_order             = 1,
         .maximum_interruption = 50
 };
 
@@ -57,8 +68,10 @@ qoscube_t qos_spec_to_cube(qosspec_t qs)
                  qs.availability >= qos_video.availability &&
                  qs.maximum_interruption <= qos_video.maximum_interruption)
                 return QOS_CUBE_VIDEO;
-        else
+        else if (qs.in_order == 1)
                 return QOS_CUBE_BE;
+        else
+                return QOS_CUBE_RAW;
 }
 
 qosspec_t qos_cube_to_spec(qoscube_t qc)
@@ -69,7 +82,8 @@ qosspec_t qos_cube_to_spec(qoscube_t qc)
         case QOS_CUBE_VIDEO:
                 return qos_video;
         case QOS_CUBE_BE:
-        default:
                 return qos_best_effort;
+        default:
+                return qos_raw;
         }
 }
-- 
cgit v1.2.3