summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Staessens <dimitri.staessens@ugent.be>2018-10-04 18:06:32 +0200
committerSander Vrijders <sander.vrijders@ugent.be>2018-10-05 09:07:47 +0200
commitb802b25ddfe6f1b6ecabe3ba70e3dac2e99e7a50 (patch)
tree94e787f0f0ca1f0254b3728b0156b2e3283d8518
parent937adca2a718b160b6d42bb8a3f28d96321fdb49 (diff)
downloadouroboros-b802b25ddfe6f1b6ecabe3ba70e3dac2e99e7a50.tar.gz
ouroboros-b802b25ddfe6f1b6ecabe3ba70e3dac2e99e7a50.zip
lib: Pass qosspec at flow allocation
The flow allocator now passes the full qos specification to the endpoint, instead of just a cube. This is a more flexible architecture, as it makes QoS cubes internal to the layers. Adds endianness transforms for the flow allocator protocol in the normal IPCP. Signed-off-by: Dimitri Staessens <dimitri.staessens@ugent.be> Signed-off-by: Sander Vrijders <sander.vrijders@ugent.be>
-rw-r--r--include/ouroboros/ipcp-dev.h2
-rw-r--r--include/ouroboros/np1_flow.h2
-rw-r--r--include/ouroboros/qos.h22
-rw-r--r--include/ouroboros/sockets.h.in11
-rw-r--r--src/ipcpd/eth/eth.c51
-rw-r--r--src/ipcpd/ipcp.c13
-rw-r--r--src/ipcpd/ipcp.h2
-rw-r--r--src/ipcpd/local/main.c4
-rw-r--r--src/ipcpd/normal/dt.c2
-rw-r--r--src/ipcpd/normal/fa.c57
-rw-r--r--src/ipcpd/normal/fa.h2
-rw-r--r--src/ipcpd/raptor/CMakeLists.txt1
-rw-r--r--src/ipcpd/raptor/main.c77
-rw-r--r--src/ipcpd/udp/main.c48
-rw-r--r--src/irmd/ipcp.c13
-rw-r--r--src/irmd/ipcp.h2
-rw-r--r--src/irmd/irm_flow.c4
-rw-r--r--src/irmd/irm_flow.h5
-rw-r--r--src/irmd/main.c22
-rw-r--r--src/lib/CMakeLists.txt4
-rw-r--r--src/lib/dev.c87
-rw-r--r--src/lib/frct.c5
-rw-r--r--src/lib/ipcpd_messages.proto3
-rw-r--r--src/lib/irmd_messages.proto3
-rw-r--r--src/lib/qos.c97
-rw-r--r--src/lib/qoscube.c30
-rw-r--r--src/lib/qosspec.proto33
-rw-r--r--src/lib/sockets.c35
28 files changed, 388 insertions, 249 deletions
diff --git a/include/ouroboros/ipcp-dev.h b/include/ouroboros/ipcp-dev.h
index 9a33c25a..a0ed026c 100644
--- a/include/ouroboros/ipcp-dev.h
+++ b/include/ouroboros/ipcp-dev.h
@@ -31,7 +31,7 @@ int ipcp_create_r(pid_t pid,
int ipcp_flow_req_arr(pid_t pid,
const uint8_t * dst,
size_t len,
- qoscube_t cube);
+ qosspec_t qs);
int ipcp_flow_alloc_reply(int fd,
int response);
diff --git a/include/ouroboros/np1_flow.h b/include/ouroboros/np1_flow.h
index 789e82df..3435c24a 100644
--- a/include/ouroboros/np1_flow.h
+++ b/include/ouroboros/np1_flow.h
@@ -29,7 +29,7 @@
int np1_flow_alloc(pid_t n_pid,
int port_id,
- qoscube_t qc);
+ qosspec_t qs);
int np1_flow_resp(int port_id);
diff --git a/include/ouroboros/qos.h b/include/ouroboros/qos.h
index 011828d7..2b93f1d0 100644
--- a/include/ouroboros/qos.h
+++ b/include/ouroboros/qos.h
@@ -27,26 +27,20 @@
#include <stdbool.h>
typedef struct qos_spec {
- uint32_t delay; /* In ms */
- uint64_t bandwidth; /* In bits/s */
- uint8_t availability; /* Class of 9s */
- uint32_t loss; /* Packet loss */
- uint8_t in_order; /* In-order delivery, enables FRCT */
- uint32_t maximum_interruption; /* In ms */
+ uint32_t delay; /* In ms */
+ uint64_t bandwidth; /* In bits/s */
+ uint8_t availability; /* Class of 9s */
+ uint32_t loss; /* Packet loss */
+ uint32_t ber; /* Bit error rate, errors per billion bits */
+ uint8_t in_order; /* In-order delivery, enables FRCT */
+ uint32_t max_gap; /* In ms */
} qosspec_t;
qosspec_t qos_raw;
+qosspec_t qos_raw_no_errors;
qosspec_t qos_best_effort;
qosspec_t qos_video;
qosspec_t qos_voice;
qosspec_t qos_data;
-__BEGIN_DECLS
-
-int qosspec_init(qosspec_t * qs);
-
-int qosspec_fini(qosspec_t * qs);
-
-__END_DECLS
-
#endif /* OUROBOROS_QOS_H */
diff --git a/include/ouroboros/sockets.h.in b/include/ouroboros/sockets.h.in
index 4557a9ef..368923db 100644
--- a/include/ouroboros/sockets.h.in
+++ b/include/ouroboros/sockets.h.in
@@ -23,6 +23,8 @@
#ifndef OUROBOROS_SOCKETS_H
#define OUROBOROS_SOCKETS_H
+#include <ouroboros/qos.h>
+
#include <sys/types.h>
#include "ipcp_config.pb-c.h"
@@ -36,6 +38,9 @@ typedef IpcpInfoMsg ipcp_info_msg_t;
#include "ipcpd_messages.pb-c.h"
typedef IpcpMsg ipcp_msg_t;
+#include "qosspec.pb-c.h"
+typedef QosspecMsg qosspec_msg_t;
+
#define SOCK_PATH "/var/run/ouroboros/"
#define SOCK_PATH_SUFFIX ".sock"
@@ -53,4 +58,10 @@ int client_socket_open(char * file_name);
irm_msg_t * send_recv_irm_msg(irm_msg_t * msg);
+
+/* qos message conversion needed in different components */
+qosspec_msg_t spec_to_msg(qosspec_t * qs);
+
+qosspec_t msg_to_spec(qosspec_msg_t * msg);
+
#endif
diff --git a/src/ipcpd/eth/eth.c b/src/ipcpd/eth/eth.c
index 44ef3756..6fd7b805 100644
--- a/src/ipcpd/eth/eth.c
+++ b/src/ipcpd/eth/eth.c
@@ -146,15 +146,27 @@
#define NAME_QUERY_REPLY 3
struct mgmt_msg {
- uint8_t code;
#if defined(BUILD_ETH_DIX)
uint16_t seid;
uint16_t deid;
#elif defined(BUILD_ETH_LLC)
uint8_t ssap;
uint8_t dsap;
+ /* QoS here for alignment */
+ uint8_t code;
+ uint8_t availability;
+#endif
+ /* QoS parameters from spec, aligned */
+ uint32_t loss;
+ uint64_t bandwidth;
+ uint32_t ber;
+ uint32_t max_gap;
+ uint32_t delay;
+ uint8_t in_order;
+#if defined (BUILD_ETH_DIX)
+ uint8_t code;
+ uint8_t availability;
#endif
- uint8_t qoscube;
int8_t response;
} __attribute__((packed));
@@ -433,7 +445,7 @@ static int eth_ipcp_alloc(const uint8_t * dst_addr,
uint8_t ssap,
#endif
const uint8_t * hash,
- qoscube_t cube)
+ qosspec_t qs)
{
uint8_t * buf;
struct mgmt_msg * msg;
@@ -453,7 +465,14 @@ static int eth_ipcp_alloc(const uint8_t * dst_addr,
#elif defined(BUILD_ETH_LLC)
msg->ssap = ssap;
#endif
- msg->qoscube = cube;
+
+ msg->delay = hton32(qs.delay);
+ msg->bandwidth = hton64(qs.bandwidth);
+ msg->availability = qs.availability;
+ msg->loss = hton32(qs.loss);
+ msg->ber = hton32(qs.ber);
+ msg->in_order = qs.in_order;
+ msg->max_gap = hton32(qs.max_gap);
memcpy(msg + 1, hash, ipcp_dir_hash_len());
@@ -523,7 +542,7 @@ static int eth_ipcp_req(uint8_t * r_addr,
uint8_t r_sap,
#endif
const uint8_t * dst,
- qoscube_t cube)
+ qosspec_t qs)
{
struct timespec ts = {0, ALLOC_TIMEO * MILLION};
struct timespec abstime;
@@ -547,7 +566,7 @@ static int eth_ipcp_req(uint8_t * r_addr,
}
/* reply to IRM, called under lock to prevent race */
- fd = ipcp_flow_req_arr(getpid(), dst, ipcp_dir_hash_len(), cube);
+ fd = ipcp_flow_req_arr(getpid(), dst, ipcp_dir_hash_len(), qs);
if (fd < 0) {
pthread_mutex_unlock(&ipcpi.alloc_lock);
log_err("Could not get new flow from IRMd.");
@@ -687,11 +706,20 @@ static int eth_ipcp_mgmt_frame(const uint8_t * buf,
uint8_t * r_addr)
{
struct mgmt_msg * msg;
+ qosspec_t qs;
msg = (struct mgmt_msg *) buf;
switch (msg->code) {
case FLOW_REQ:
+ qs.delay = ntoh32(msg->delay);
+ qs.bandwidth = ntoh64(msg->bandwidth);
+ qs.availability = msg->availability;
+ qs.loss = ntoh32(msg->loss);
+ qs.ber = ntoh32(msg->ber);
+ qs.in_order = msg->in_order;
+ qs.max_gap = ntoh32(msg->max_gap);
+
if (shim_data_reg_has(eth_data.shim_data,
buf + sizeof(*msg))) {
eth_ipcp_req(r_addr,
@@ -701,7 +729,7 @@ static int eth_ipcp_mgmt_frame(const uint8_t * buf,
msg->ssap,
#endif
buf + sizeof(*msg),
- msg->qoscube);
+ qs);
}
break;
case FLOW_REPLY:
@@ -1553,7 +1581,7 @@ static int eth_ipcp_query(const uint8_t * hash)
static int eth_ipcp_flow_alloc(int fd,
const uint8_t * hash,
- qoscube_t cube)
+ qosspec_t qs)
{
#ifdef BUILD_ETH_LLC
uint8_t ssap = 0;
@@ -1565,11 +1593,6 @@ static int eth_ipcp_flow_alloc(int fd,
assert(hash);
- if (cube > QOS_CUBE_DATA) {
- log_dbg("Unsupported QoS requested.");
- return -1;
- }
-
if (!shim_data_dir_has(eth_data.shim_data, hash)) {
log_err("Destination unreachable.");
return -1;
@@ -1597,7 +1620,7 @@ static int eth_ipcp_flow_alloc(int fd,
#elif defined(BUILD_ETH_LLC)
ssap,
#endif
- hash, cube) < 0) {
+ hash, qs) < 0) {
#ifdef BUILD_ETH_LLC
pthread_rwlock_wrlock(&eth_data.flows_lock);
bmp_release(eth_data.saps, eth_data.fd_to_ef[fd].sap);
diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c
index 5ea54533..e415bbd9 100644
--- a/src/ipcpd/ipcp.c
+++ b/src/ipcpd/ipcp.c
@@ -20,6 +20,13 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
+#if defined(__linux__) || defined(__CYGWIN__)
+#define _DEFAULT_SOURCE
+#else
+#define _POSIX_C_SOURCE 200112L
+#define __XSI_VISIBLE 500
+#endif
+
#if defined(__linux__) && !defined(DISABLE_CORE_LOCK)
#define _GNU_SOURCE
#define NPROC (sysconf(_SC_NPROCESSORS_ONLN))
@@ -198,6 +205,7 @@ static void * mainloop(void * o)
layer_info_msg_t layer_info = LAYER_INFO_MSG__INIT;
int fd = -1;
struct cmd * cmd;
+ qosspec_t qs;
ret_msg.code = IPCP_MSG_CODE__IPCP_REPLY;
@@ -422,9 +430,10 @@ static void * mainloop(void * o)
break;
}
+ qs = msg_to_spec(msg->qosspec);
fd = np1_flow_alloc(msg->pid,
msg->port_id,
- msg->qoscube);
+ qs);
if (fd < 0) {
log_err("Failed allocating fd on port_id %d.",
msg->port_id);
@@ -435,7 +444,7 @@ static void * mainloop(void * o)
ret_msg.result =
ipcpi.ops->ipcp_flow_alloc(fd,
msg->hash.data,
- msg->qoscube);
+ qs);
break;
case IPCP_MSG_CODE__IPCP_FLOW_ALLOC_RESP:
ret_msg.has_result = true;
diff --git a/src/ipcpd/ipcp.h b/src/ipcpd/ipcp.h
index 5417fc74..13751b6d 100644
--- a/src/ipcpd/ipcp.h
+++ b/src/ipcpd/ipcp.h
@@ -60,7 +60,7 @@ struct ipcp_ops {
int (* ipcp_flow_alloc)(int fd,
const uint8_t * dst,
- qoscube_t qos);
+ qosspec_t qs);
int (* ipcp_flow_alloc_resp)(int fd,
int response);
diff --git a/src/ipcpd/local/main.c b/src/ipcpd/local/main.c
index c83f85fe..8eae7503 100644
--- a/src/ipcpd/local/main.c
+++ b/src/ipcpd/local/main.c
@@ -183,7 +183,7 @@ static int ipcp_local_query(const uint8_t * hash)
static int ipcp_local_flow_alloc(int fd,
const uint8_t * dst,
- qoscube_t cube)
+ qosspec_t qs)
{
struct timespec ts = {0, ALLOC_TIMEOUT * MILLION};
struct timespec abstime;
@@ -212,7 +212,7 @@ static int ipcp_local_flow_alloc(int fd,
assert(ipcpi.alloc_id == -1);
- out_fd = ipcp_flow_req_arr(getpid(), dst, ipcp_dir_hash_len(), cube);
+ out_fd = ipcp_flow_req_arr(getpid(), dst, ipcp_dir_hash_len(), qs);
if (out_fd < 0) {
pthread_mutex_unlock(&ipcpi.alloc_lock);
log_dbg("Flow allocation failed: %d", out_fd);
diff --git a/src/ipcpd/normal/dt.c b/src/ipcpd/normal/dt.c
index c3f8f198..a350e4be 100644
--- a/src/ipcpd/normal/dt.c
+++ b/src/ipcpd/normal/dt.c
@@ -31,8 +31,6 @@
#define DT "dt"
#define OUROBOROS_PREFIX DT
-/* FIXME: fix #defines and remove endian.h include. */
-#include <ouroboros/endian.h>
#include <ouroboros/bitmap.h>
#include <ouroboros/errno.h>
#include <ouroboros/logs.h>
diff --git a/src/ipcpd/normal/fa.c b/src/ipcpd/normal/fa.c
index 10f0a863..4c82e0e0 100644
--- a/src/ipcpd/normal/fa.c
+++ b/src/ipcpd/normal/fa.c
@@ -57,8 +57,15 @@ struct fa_msg {
uint32_t r_eid;
uint32_t s_eid;
uint8_t code;
- uint8_t qc;
int8_t response;
+ /* QoS parameters from spec, aligned */
+ uint8_t availability;
+ uint8_t in_order;
+ uint32_t delay;
+ uint64_t bandwidth;
+ uint32_t loss;
+ uint32_t ber;
+ uint32_t max_gap;
} __attribute__((packed));
struct {
@@ -100,6 +107,7 @@ static void fa_post_sdu(void * comp,
int fd;
uint8_t * buf;
struct fa_msg * msg;
+ qosspec_t qs;
(void) comp;
@@ -142,10 +150,18 @@ static void fa_post_sdu(void * comp,
assert(ipcpi.alloc_id == -1);
+ qs.delay = ntoh32(msg->delay);
+ qs.bandwidth = ntoh64(msg->bandwidth);
+ qs.availability = msg->availability;
+ qs.loss = ntoh32(msg->loss);
+ qs.ber = ntoh32(msg->ber);
+ qs.in_order = msg->in_order;
+ qs.max_gap = ntoh32(msg->max_gap);
+
fd = ipcp_flow_req_arr(getpid(),
(uint8_t *) (msg + 1),
ipcp_dir_hash_len(),
- msg->qc);
+ qs);
if (fd < 0) {
pthread_mutex_unlock(&ipcpi.alloc_lock);
log_err("Failed to get fd for flow.");
@@ -155,8 +171,8 @@ static void fa_post_sdu(void * comp,
pthread_rwlock_wrlock(&fa.flows_lock);
- fa.r_eid[fd] = msg->s_eid;
- fa.r_addr[fd] = msg->s_addr;
+ fa.r_eid[fd] = ntoh32(msg->s_eid);
+ fa.r_addr[fd] = ntoh64(msg->s_addr);
pthread_rwlock_unlock(&fa.flows_lock);
@@ -169,14 +185,14 @@ static void fa_post_sdu(void * comp,
case FLOW_REPLY:
pthread_rwlock_wrlock(&fa.flows_lock);
- fa.r_eid[msg->r_eid] = msg->s_eid;
+ fa.r_eid[ntoh32(msg->r_eid)] = ntoh32(msg->s_eid);
- ipcp_flow_alloc_reply(msg->r_eid, msg->response);
+ ipcp_flow_alloc_reply(ntoh32(msg->r_eid), msg->response);
if (msg->response < 0)
- destroy_conn(msg->r_eid);
+ destroy_conn(ntoh32(msg->r_eid));
else
- sdu_sched_add(fa.sdu_sched, msg->r_eid);
+ sdu_sched_add(fa.sdu_sched, ntoh32(msg->r_eid));
pthread_rwlock_unlock(&fa.flows_lock);
@@ -227,11 +243,12 @@ void fa_stop(void)
int fa_alloc(int fd,
const uint8_t * dst,
- qoscube_t qc)
+ qosspec_t qs)
{
struct fa_msg * msg;
uint64_t addr;
struct shm_du_buff * sdb;
+ qoscube_t qc;
addr = dir_query(dst);
if (addr == 0)
@@ -240,14 +257,22 @@ int fa_alloc(int fd,
if (ipcp_sdb_reserve(&sdb, sizeof(*msg) + ipcp_dir_hash_len()))
return -1;
- msg = (struct fa_msg *) shm_du_buff_head(sdb);
- msg->code = FLOW_REQ;
- msg->qc = qc;
- msg->s_eid = fd;
- msg->s_addr = ipcpi.dt_addr;
+ msg = (struct fa_msg *) shm_du_buff_head(sdb);
+ msg->code = FLOW_REQ;
+ msg->s_eid = hton32(fd);
+ msg->s_addr = hton64(ipcpi.dt_addr);
+ msg->delay = hton32(qs.delay);
+ msg->bandwidth = hton64(qs.bandwidth);
+ msg->availability = qs.availability;
+ msg->loss = hton32(qs.loss);
+ msg->ber = hton32(qs.ber);
+ msg->in_order = qs.in_order;
+ msg->max_gap = hton32(qs.max_gap);
memcpy(msg + 1, dst, ipcp_dir_hash_len());
+ qc = qos_spec_to_cube(qs);
+
if (dt_write_sdu(addr, qc, fa.fd, sdb)) {
ipcp_sdb_release(sdb);
return -1;
@@ -302,8 +327,8 @@ int fa_alloc_resp(int fd,
msg = (struct fa_msg *) shm_du_buff_head(sdb);
msg->code = FLOW_REPLY;
- msg->r_eid = fa.r_eid[fd];
- msg->s_eid = fd;
+ msg->r_eid = hton32(fa.r_eid[fd]);
+ msg->s_eid = hton32(fd);
msg->response = response;
if (response < 0) {
diff --git a/src/ipcpd/normal/fa.h b/src/ipcpd/normal/fa.h
index 87819d6f..a98d834a 100644
--- a/src/ipcpd/normal/fa.h
+++ b/src/ipcpd/normal/fa.h
@@ -36,7 +36,7 @@ void fa_stop(void);
int fa_alloc(int fd,
const uint8_t * dst,
- qoscube_t qos);
+ qosspec_t qs);
int fa_alloc_resp(int fd,
int response);
diff --git a/src/ipcpd/raptor/CMakeLists.txt b/src/ipcpd/raptor/CMakeLists.txt
index 06e6ee29..1883d9bb 100644
--- a/src/ipcpd/raptor/CMakeLists.txt
+++ b/src/ipcpd/raptor/CMakeLists.txt
@@ -16,6 +16,7 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
find_path(RAPTOR_KERNEL_MODULE
NAMES
raptor.ko.gz
+ raptor.ko.xz
HINTS
/lib/modules/${CMAKE_SYSTEM_VERSION}/extra
)
diff --git a/src/ipcpd/raptor/main.c b/src/ipcpd/raptor/main.c
index 4f0099b3..a01889ec 100644
--- a/src/ipcpd/raptor/main.c
+++ b/src/ipcpd/raptor/main.c
@@ -90,11 +90,18 @@
#define NAME_QUERY_REPLY 3
struct mgmt_msg {
- uint8_t code;
- uint8_t ssap;
- uint8_t dsap;
- uint8_t qoscube;
- int8_t response;
+ uint8_t code;
+ uint8_t ssap;
+ uint8_t dsap;
+ int8_t response;
+ /* QoS parameters from spec, aligned */
+ uint32_t loss;
+ uint64_t bandwidth;
+ uint32_t ber;
+ uint32_t max_gap;
+ uint32_t delay;
+ uint8_t in_order;
+ uint8_t availability;
} __attribute__((packed));
struct ef {
@@ -278,7 +285,7 @@ static int raptor_send_frame(struct shm_du_buff * sdb,
static int raptor_sap_alloc(uint8_t ssap,
const uint8_t * hash,
- qoscube_t cube)
+ qosspec_t qs)
{
struct mgmt_msg * msg;
struct shm_du_buff * sdb;
@@ -288,10 +295,16 @@ static int raptor_sap_alloc(uint8_t ssap,
return -1;
}
- msg = (struct mgmt_msg *) shm_du_buff_head(sdb);
- msg->code = FLOW_REQ;
- msg->ssap = ssap;
- msg->qoscube = cube;
+ msg = (struct mgmt_msg *) shm_du_buff_head(sdb);
+ msg->code = FLOW_REQ;
+ msg->ssap = ssap;
+ msg->delay = hton32(qs.delay);
+ msg->bandwidth = hton64(qs.bandwidth);
+ msg->availability = qs.availability;
+ msg->loss = hton32(qs.loss);
+ msg->ber = hton32(qs.ber);
+ msg->in_order = qs.in_order;
+ msg->max_gap = hton32(qs.max_gap);
memcpy(msg + 1, hash, ipcp_dir_hash_len());
@@ -306,15 +319,15 @@ static int raptor_sap_alloc(uint8_t ssap,
return 0;
}
-static int raptor_sap_alloc_resp(uint8_t ssap,
- uint8_t dsap,
- int response)
+static int raptor_sap_alloc_resp(uint8_t ssap,
+ uint8_t dsap,
+ int response)
{
- struct mgmt_msg * msg;
+ struct mgmt_msg * msg;
struct shm_du_buff * sdb;
if (ipcp_sdb_reserve(&sdb, sizeof(*msg)) < 0) {
- log_err("failed to reserve sdb for management frame.");
+ log_err("Failed to reserve sdb for management frame.");
return -1;
}
@@ -337,7 +350,7 @@ static int raptor_sap_alloc_resp(uint8_t ssap,
static int raptor_sap_req(uint8_t r_sap,
const uint8_t * dst,
- qoscube_t cube)
+ qosspec_t qs)
{
struct timespec ts = {0, EVENT_WAIT_TIMEOUT * 1000};
struct timespec abstime;
@@ -361,7 +374,7 @@ static int raptor_sap_req(uint8_t r_sap,
}
/* reply to IRM, called under lock to prevent race */
- fd = ipcp_flow_req_arr(getpid(), dst, ipcp_dir_hash_len(), cube);
+ fd = ipcp_flow_req_arr(getpid(), dst, ipcp_dir_hash_len(), qs);
if (fd < 0) {
pthread_mutex_unlock(&ipcpi.alloc_lock);
log_err("Could not get new flow from IRMd.");
@@ -424,12 +437,12 @@ static int raptor_name_query_req(const uint8_t * hash)
return 0;
if (ipcp_sdb_reserve(&sdb, sizeof(*msg) + ipcp_dir_hash_len()) < 0) {
- log_err("failed to reserve sdb for management frame.");
+ log_err("Failed to reserve sdb for management frame.");
return -1;
}
- msg = (struct mgmt_msg *) shm_du_buff_head(sdb);
- msg->code = NAME_QUERY_REPLY;
+ msg = (struct mgmt_msg *) shm_du_buff_head(sdb);
+ msg->code = NAME_QUERY_REPLY;
memcpy(msg + 1, hash, ipcp_dir_hash_len());
@@ -456,8 +469,9 @@ static int raptor_name_query_reply(const uint8_t * hash)
static int raptor_mgmt_frame(const uint8_t * buf,
size_t len)
{
- struct mgmt_msg * msg = (struct mgmt_msg *) buf;
- uint8_t * hash = (uint8_t *) (msg + 1);
+ struct mgmt_msg * msg = (struct mgmt_msg *) buf;
+ uint8_t * hash = (uint8_t *) (msg + 1);
+ qosspec_t qs;
switch (msg->code) {
case FLOW_REQ:
@@ -466,8 +480,16 @@ static int raptor_mgmt_frame(const uint8_t * buf,
return -1;
}
+ qs.delay = ntoh32(msg->delay);
+ qs.bandwidth = ntoh64(msg->bandwidth);
+ qs.availability = msg->availability;
+ qs.loss = ntoh32(msg->loss);
+ qs.ber = ntoh32(msg->ber);
+ qs.in_order = msg->in_order;
+ qs.max_gap = ntoh32(msg->max_gap);
+
if (shim_data_reg_has(raptor_data.shim_data, hash))
- raptor_sap_req(msg->ssap, hash, msg->qoscube);
+ raptor_sap_req(msg->ssap, hash, qs);
break;
case FLOW_REPLY:
if (len != sizeof(*msg)) {
@@ -901,7 +923,7 @@ static int raptor_query(const uint8_t * hash)
static int raptor_flow_alloc(int fd,
const uint8_t * hash,
- qoscube_t cube)
+ qosspec_t qs)
{
uint8_t ssap = 0;
@@ -909,11 +931,6 @@ static int raptor_flow_alloc(int fd,
assert(hash);
- if (cube != QOS_CUBE_BE) {
- log_dbg("Unsupported QoS requested.");
- return -1;
- }
-
if (!shim_data_dir_has(raptor_data.shim_data, hash)) {
log_err("Destination unreachable.");
return -1;
@@ -932,7 +949,7 @@ static int raptor_flow_alloc(int fd,
pthread_rwlock_unlock(&raptor_data.flows_lock);
- if (raptor_sap_alloc(ssap, hash, cube) < 0) {
+ if (raptor_sap_alloc(ssap, hash, qs) < 0) {
pthread_rwlock_wrlock(&raptor_data.flows_lock);
bmp_release(raptor_data.saps, raptor_data.fd_to_ef[fd].sap);
raptor_data.fd_to_ef[fd].sap = -1;
diff --git a/src/ipcpd/udp/main.c b/src/ipcpd/udp/main.c
index 6a350da0..96820662 100644
--- a/src/ipcpd/udp/main.c
+++ b/src/ipcpd/udp/main.c
@@ -73,8 +73,15 @@ struct mgmt_msg {
uint16_t src_udp_port;
uint16_t dst_udp_port;
uint8_t code;
- uint8_t qoscube;
uint8_t response;
+ /* QoS parameters from spec, aligned */
+ uint8_t availability;
+ uint8_t in_order;
+ uint32_t delay;
+ uint64_t bandwidth;
+ uint32_t loss;
+ uint32_t ber;
+ uint32_t max_gap;
} __attribute__((packed));
struct uf {
@@ -219,7 +226,7 @@ static int send_shim_udp_msg(uint8_t * buf,
static int ipcp_udp_port_alloc(uint32_t dst_ip_addr,
uint16_t src_udp_port,
const uint8_t * dst,
- qoscube_t cube)
+ qosspec_t qs)
{
uint8_t * buf;
struct mgmt_msg * msg;
@@ -235,7 +242,13 @@ static int ipcp_udp_port_alloc(uint32_t dst_ip_addr,
msg = (struct mgmt_msg *) buf;
msg->code = FLOW_REQ;
msg->src_udp_port = src_udp_port;
- msg->qoscube = cube;
+ msg->delay = hton32(qs.delay);
+ msg->bandwidth = hton64(qs.bandwidth);
+ msg->availability = qs.availability;
+ msg->loss = hton32(qs.loss);
+ msg->ber = hton32(qs.ber);
+ msg->in_order = qs.in_order;
+ msg->max_gap = hton32(qs.max_gap);
memcpy(msg + 1, dst, ipcp_dir_hash_len());
@@ -272,7 +285,7 @@ static int ipcp_udp_port_alloc_resp(uint32_t dst_ip_addr,
static int ipcp_udp_port_req(struct sockaddr_in * c_saddr,
const uint8_t * dst,
- qoscube_t cube)
+ qosspec_t qs)
{
struct timespec ts = {0, FD_UPDATE_TIMEOUT * 1000};
struct timespec abstime;
@@ -331,7 +344,7 @@ static int ipcp_udp_port_req(struct sockaddr_in * c_saddr,
}
/* reply to IRM */
- fd = ipcp_flow_req_arr(getpid(), dst, ipcp_dir_hash_len(), cube);
+ fd = ipcp_flow_req_arr(getpid(), dst, ipcp_dir_hash_len(), qs);
if (fd < 0) {
pthread_mutex_unlock(&ipcpi.alloc_lock);
log_err("Could not get new flow from IRMd.");
@@ -436,7 +449,7 @@ static void * ipcp_udp_listener(void * o)
while (true) {
struct mgmt_msg * msg = NULL;
-
+ qosspec_t qs;
memset(&buf, 0, SHIM_UDP_MSG_SIZE);
n = recvfrom(sfd, buf, SHIM_UDP_MSG_SIZE, 0,
(struct sockaddr *) &c_saddr,
@@ -455,9 +468,16 @@ static void * ipcp_udp_listener(void * o)
switch (msg->code) {
case FLOW_REQ:
c_saddr.sin_port = msg->src_udp_port;
+ qs.delay = ntoh32(msg->delay);
+ qs.bandwidth = ntoh64(msg->bandwidth);
+ qs.availability = msg->availability;
+ qs.loss = ntoh32(msg->loss);
+ qs.ber = ntoh32(msg->ber);
+ qs.in_order = msg->in_order;
+ qs.max_gap = ntoh32(msg->max_gap);
ipcp_udp_port_req(&c_saddr,
(uint8_t *) (msg + 1),
- msg->qoscube);
+ qs);
break;
case FLOW_REPLY:
ipcp_udp_port_alloc_reply(msg->src_udp_port,
@@ -555,7 +575,8 @@ static void * ipcp_udp_sdu_loop(void * o)
pthread_rwlock_unlock(&udp_data.flows_lock);
- pthread_cleanup_push((void (*)(void *)) ipcp_sdb_release,
+ pthread_cleanup_push((void (*)(void *))
+ ipcp_sdb_release,
(void *) sdb);
if (send(fd, shm_du_buff_head(sdb),
@@ -968,7 +989,7 @@ static int ipcp_udp_query(const uint8_t * hash)
static int ipcp_udp_flow_alloc(int fd,
const uint8_t * dst,
- qoscube_t cube)
+ qosspec_t qs)
{
struct sockaddr_in r_saddr; /* server address */
struct sockaddr_in f_saddr; /* flow */
@@ -978,12 +999,9 @@ static int ipcp_udp_flow_alloc(int fd,
log_dbg("Allocating flow to " HASH_FMT ".", HASH_VAL(dst));
- assert(dst);
+ (void) qs;
- if (cube > QOS_CUBE_DATA) {
- log_dbg("Unsupported QoS requested.");
- return -1;
- }
+ assert(dst);
skfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (skfd < 0)
@@ -1034,7 +1052,7 @@ static int ipcp_udp_flow_alloc(int fd,
pthread_rwlock_unlock(&udp_data.flows_lock);
- if (ipcp_udp_port_alloc(ip_addr, f_saddr.sin_port, dst, cube) < 0) {
+ if (ipcp_udp_port_alloc(ip_addr, f_saddr.sin_port, dst, qs) < 0) {
pthread_rwlock_wrlock(&udp_data.flows_lock);
udp_data.fd_to_uf[fd].udp = -1;
diff --git a/src/irmd/ipcp.c b/src/irmd/ipcp.c
index dc8f1c6e..0bdf674b 100644
--- a/src/irmd/ipcp.c
+++ b/src/irmd/ipcp.c
@@ -433,11 +433,12 @@ int ipcp_flow_alloc(pid_t pid,
pid_t n_pid,
const uint8_t * dst,
size_t len,
- qoscube_t cube)
+ qosspec_t qs)
{
- ipcp_msg_t msg = IPCP_MSG__INIT;
- ipcp_msg_t * recv_msg = NULL;
- int ret = -1;
+ ipcp_msg_t msg = IPCP_MSG__INIT;
+ qosspec_msg_t qs_msg;
+ ipcp_msg_t * recv_msg = NULL;
+ int ret = -1;
assert(dst);
@@ -449,8 +450,8 @@ int ipcp_flow_alloc(pid_t pid,
msg.has_hash = true;
msg.hash.len = len;
msg.hash.data = (uint8_t *) dst;
- msg.has_qoscube = true;
- msg.qoscube = cube;
+ qs_msg = spec_to_msg(&qs);
+ msg.qosspec = &qs_msg;
recv_msg = send_recv_ipcp_msg(pid, &msg);
if (recv_msg == NULL)
diff --git a/src/irmd/ipcp.h b/src/irmd/ipcp.h
index 8ff062b2..28396333 100644
--- a/src/irmd/ipcp.h
+++ b/src/irmd/ipcp.h
@@ -67,7 +67,7 @@ int ipcp_flow_alloc(pid_t pid,
pid_t n_pid,
const uint8_t * dst,
size_t len,
- qoscube_t qos);
+ qosspec_t qs);
int ipcp_flow_alloc_resp(pid_t pid,
int port_id,
diff --git a/src/irmd/irm_flow.c b/src/irmd/irm_flow.c
index dfbe5e95..a5a9f28c 100644
--- a/src/irmd/irm_flow.c
+++ b/src/irmd/irm_flow.c
@@ -39,7 +39,7 @@
struct irm_flow * irm_flow_create(pid_t n_pid,
pid_t n_1_pid,
int port_id,
- qoscube_t qc)
+ qosspec_t qs)
{
pthread_condattr_t cattr;
struct irm_flow * f = malloc(sizeof(*f));
@@ -61,7 +61,7 @@ struct irm_flow * irm_flow_create(pid_t n_pid,
f->n_pid = n_pid;
f->n_1_pid = n_1_pid;
f->port_id = port_id;
- f->qc = qc;
+ f->qs = qs;
f->n_rb = shm_rbuff_create(n_pid, port_id);
if (f->n_rb == NULL) {
diff --git a/src/irmd/irm_flow.h b/src/irmd/irm_flow.h
index d53984e8..f4de8187 100644
--- a/src/irmd/irm_flow.h
+++ b/src/irmd/irm_flow.h
@@ -43,11 +43,12 @@ struct irm_flow {
struct list_head next;
int port_id;
- qoscube_t qc;
pid_t n_pid;
pid_t n_1_pid;
+ qosspec_t qs;
+
struct shm_rbuff * n_rb;
struct shm_rbuff * n_1_rb;
@@ -61,7 +62,7 @@ struct irm_flow {
struct irm_flow * irm_flow_create(pid_t n_pid,
pid_t n_1_pid,
int port_id,
- qoscube_t qc);
+ qosspec_t qs);
void irm_flow_destroy(struct irm_flow * f);
diff --git a/src/irmd/main.c b/src/irmd/main.c
index 634bf4de..9504f3b5 100644
--- a/src/irmd/main.c
+++ b/src/irmd/main.c
@@ -1264,7 +1264,7 @@ static int flow_accept(pid_t pid,
static int flow_alloc(pid_t pid,
const char * dst,
- qoscube_t cube,
+ qosspec_t qs,
struct timespec * timeo,
struct irm_flow ** e)
{
@@ -1288,7 +1288,7 @@ static int flow_alloc(pid_t pid,
return -EBADF;
}
- f = irm_flow_create(pid, ipcp->pid, port_id, cube);
+ f = irm_flow_create(pid, ipcp->pid, port_id, qs);
if (f == NULL) {
bmp_release(irmd.port_ids, port_id);
pthread_rwlock_unlock(&irmd.flows_lock);
@@ -1310,7 +1310,7 @@ static int flow_alloc(pid_t pid,
str_hash(ipcp->dir_hash_algo, hash, dst);
if (ipcp_flow_alloc(ipcp->pid, port_id, pid, hash,
- IPCP_HASH_LEN(ipcp), cube)) {
+ IPCP_HASH_LEN(ipcp), qs)) {
/* sanitizer cleans this */
log_info("Flow_allocation failed.");
free(hash);
@@ -1418,7 +1418,7 @@ static pid_t auto_execute(char ** argv)
static struct irm_flow * flow_req_arr(pid_t pid,
const uint8_t * hash,
- qoscube_t cube)
+ qosspec_t qs)
{
struct reg_entry * re = NULL;
struct prog_entry * a = NULL;
@@ -1521,7 +1521,7 @@ static struct irm_flow * flow_req_arr(pid_t pid,
return NULL;
}
- f = irm_flow_create(h_pid, pid, port_id, cube);
+ f = irm_flow_create(h_pid, pid, port_id, qs);
if (f == NULL) {
bmp_release(irmd.port_ids, port_id);
pthread_rwlock_unlock(&irmd.flows_lock);
@@ -1993,17 +1993,19 @@ static void * mainloop(void * o)
case IRM_MSG_CODE__IRM_FLOW_ACCEPT:
result = flow_accept(msg->pid, timeo, &e);
if (result == 0) {
+ qosspec_msg_t qs_msg;
ret_msg->has_port_id = true;
ret_msg->port_id = e->port_id;
ret_msg->has_pid = true;
ret_msg->pid = e->n_1_pid;
- ret_msg->has_qoscube = true;
- ret_msg->qoscube = e->qc;
+ qs_msg = spec_to_msg(&e->qs);
+ ret_msg->qosspec = &qs_msg;
}
break;
case IRM_MSG_CODE__IRM_FLOW_ALLOC:
result = flow_alloc(msg->pid, msg->dst,
- msg->qoscube, timeo, &e);
+ msg_to_spec(msg->qosspec),
+ timeo, &e);
if (result == 0) {
ret_msg->has_port_id = true;
ret_msg->port_id = e->port_id;
@@ -2017,7 +2019,7 @@ static void * mainloop(void * o)
case IRM_MSG_CODE__IPCP_FLOW_REQ_ARR:
e = flow_req_arr(msg->pid,
msg->hash.data,
- msg->qoscube);
+ msg_to_spec(msg->qosspec));
result = (e == NULL ? -1 : 0);
if (result == 0) {
ret_msg->has_port_id = true;
@@ -2061,6 +2063,8 @@ static void * mainloop(void * o)
irm_msg__pack(ret_msg, buffer.data);
+ /* Can't free the qosspec. */
+ ret_msg->qosspec = NULL;
irm_msg__free_unpacked(ret_msg, NULL);
pthread_cleanup_push(close_ptr, &sfd);
diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt
index e7e07802..aa4e5bf3 100644
--- a/src/lib/CMakeLists.txt
+++ b/src/lib/CMakeLists.txt
@@ -6,6 +6,8 @@ include_directories(${CMAKE_BINARY_DIR}/include)
protobuf_generate_c(IRM_PROTO_SRCS IRM_PROTO_HDRS irmd_messages.proto)
protobuf_generate_c(IPCP_PROTO_SRCS IPCP_PROTO_HDRS ipcpd_messages.proto)
+protobuf_generate_c(QOSSPEC_PROTO_SRCS QOSSPEC_PROTO_HDRS
+ qosspec.proto)
protobuf_generate_c(LAYER_CONFIG_PROTO_SRCS LAYER_CONFIG_PROTO_HDRS
ipcp_config.proto)
protobuf_generate_c(CACEP_PROTO_SRCS CACEP_PROTO_HDRS cacep.proto)
@@ -214,7 +216,7 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/config.h.in"
"${CMAKE_CURRENT_BINARY_DIR}/config.h" @ONLY)
add_library(ouroboros-common SHARED ${SOURCE_FILES_COMMON} ${IRM_PROTO_SRCS}
- ${IPCP_PROTO_SRCS} ${LAYER_CONFIG_PROTO_SRCS})
+ ${IPCP_PROTO_SRCS} ${LAYER_CONFIG_PROTO_SRCS} ${QOSSPEC_PROTO_SRCS})
add_library(ouroboros-dev SHARED ${SOURCE_FILES_DEV} ${CACEP_PROTO_SRCS})
diff --git a/src/lib/dev.c b/src/lib/dev.c
index 3d9e1d49..a92c1e42 100644
--- a/src/lib/dev.c
+++ b/src/lib/dev.c
@@ -44,7 +44,6 @@
#include <ouroboros/shm_rbuff.h>
#include <ouroboros/utils.h>
#include <ouroboros/fqueue.h>
-#include <ouroboros/qoscube.h>
#include <ouroboros/timerwheel.h>
#include <stdlib.h>
@@ -94,7 +93,6 @@ struct flow {
struct shm_flow_set * set;
int port_id;
int oflags;
- qoscube_t cube;
qosspec_t spec;
ssize_t part_idx;
@@ -235,7 +233,6 @@ static void flow_clear(int fd)
ai.flows[fd].port_id = -1;
ai.flows[fd].pid = -1;
- ai.flows[fd].cube = QOS_CUBE_BE;
}
static void flow_fini(int fd)
@@ -272,7 +269,7 @@ static void flow_fini(int fd)
static int flow_init(int port_id,
pid_t pid,
- qoscube_t qc)
+ qosspec_t qs)
{
int fd;
int err = -ENOMEM;
@@ -300,9 +297,8 @@ static int flow_init(int port_id,
ai.flows[fd].port_id = port_id;
ai.flows[fd].oflags = FLOWFDEFAULT;
ai.flows[fd].pid = pid;
- ai.flows[fd].cube = qc;
- ai.flows[fd].spec = qos_cube_to_spec(qc);
ai.flows[fd].part_idx = NO_PART;
+ ai.flows[fd].spec = qs;
ai.ports[port_id].fd = fd;
@@ -499,7 +495,6 @@ 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;
@@ -528,14 +523,13 @@ int flow_accept(qosspec_t * qs,
}
if (!recv_msg->has_pid || !recv_msg->has_port_id ||
- !recv_msg->has_qoscube) {
+ recv_msg->qosspec == NULL) {
irm_msg__free_unpacked(recv_msg, NULL);
return -EIRMD;
}
- qc = recv_msg->qoscube;
-
- fd = flow_init(recv_msg->port_id, recv_msg->pid, recv_msg->qoscube);
+ fd = flow_init(recv_msg->port_id, recv_msg->pid,
+ msg_to_spec(recv_msg->qosspec));
irm_msg__free_unpacked(recv_msg, NULL);
@@ -544,12 +538,10 @@ int flow_accept(qosspec_t * qs,
pthread_rwlock_wrlock(&ai.lock);
- /* FIXME: check if FRCT is needed based on qc? */
-
assert(ai.flows[fd].frcti == NULL);
- if (qc != QOS_CUBE_RAW) {
- ai.flows[fd].frcti = frcti_create(fd, qc);
+ if (ai.flows[fd].spec.in_order != 0) {
+ ai.flows[fd].frcti = frcti_create(fd);
if (ai.flows[fd].frcti == NULL) {
flow_fini(fd);
pthread_rwlock_unlock(&ai.lock);
@@ -569,21 +561,17 @@ int flow_alloc(const char * dst,
qosspec_t * qs,
const struct timespec * timeo)
{
- irm_msg_t msg = IRM_MSG__INIT;
- irm_msg_t * recv_msg;
- qoscube_t qc = QOS_CUBE_RAW;
- int fd;
-
- msg.code = IRM_MSG_CODE__IRM_FLOW_ALLOC;
- msg.dst = (char *) dst;
- msg.has_pid = true;
- msg.has_qoscube = true;
- msg.pid = ai.pid;
-
- if (qs != NULL)
- qc = qos_spec_to_cube(*qs);
+ irm_msg_t msg = IRM_MSG__INIT;
+ qosspec_msg_t qs_msg = QOSSPEC_MSG__INIT;
+ irm_msg_t * recv_msg;
+ int fd;
- msg.qoscube = qc;
+ msg.code = IRM_MSG_CODE__IRM_FLOW_ALLOC;
+ msg.dst = (char *) dst;
+ msg.has_pid = true;
+ msg.pid = ai.pid;
+ qs_msg = spec_to_msg(qs);
+ msg.qosspec = &qs_msg;
if (timeo != NULL) {
msg.has_timeo_sec = true;
@@ -612,7 +600,8 @@ int flow_alloc(const char * dst,
return -EIRMD;
}
- fd = flow_init(recv_msg->port_id, recv_msg->pid, qc);
+ fd = flow_init(recv_msg->port_id, recv_msg->pid,
+ qs == NULL ? qos_raw : *qs);
irm_msg__free_unpacked(recv_msg, NULL);
@@ -623,8 +612,8 @@ int flow_alloc(const char * dst,
assert(ai.flows[fd].frcti == NULL);
- if (qc != QOS_CUBE_RAW) {
- ai.flows[fd].frcti = frcti_create(fd, qc);
+ if (ai.flows[fd].spec.in_order != 0) {
+ ai.flows[fd].frcti = frcti_create(fd);
if (ai.flows[fd].frcti == NULL) {
flow_fini(fd);
pthread_rwlock_unlock(&ai.lock);
@@ -1178,9 +1167,9 @@ int fevent(struct flow_set * set,
int np1_flow_alloc(pid_t n_pid,
int port_id,
- qoscube_t qc)
+ qosspec_t qs)
{
- return flow_init(port_id, n_pid, qc);
+ return flow_init(port_id, n_pid, qs);
}
int np1_flow_dealloc(int port_id)
@@ -1243,25 +1232,25 @@ int ipcp_create_r(pid_t pid,
int ipcp_flow_req_arr(pid_t pid,
const uint8_t * dst,
size_t len,
- qoscube_t qc)
+ qosspec_t qs)
{
- irm_msg_t msg = IRM_MSG__INIT;
- irm_msg_t * recv_msg;
- int fd;
+ irm_msg_t msg = IRM_MSG__INIT;
+ irm_msg_t * recv_msg;
+ qosspec_msg_t qs_msg;
+ int fd;
assert(dst != NULL);
- msg.code = IRM_MSG_CODE__IPCP_FLOW_REQ_ARR;
- msg.has_pid = true;
- msg.pid = pid;
- msg.has_hash = true;
- msg.hash.len = len;
- msg.hash.data = (uint8_t *) dst;
- msg.has_qoscube = true;
- msg.qoscube = qc;
+ msg.code = IRM_MSG_CODE__IPCP_FLOW_REQ_ARR;
+ msg.has_pid = true;
+ msg.pid = pid;
+ msg.has_hash = true;
+ msg.hash.len = len;
+ msg.hash.data = (uint8_t *) dst;
+ qs_msg = spec_to_msg(&qs);
+ msg.qosspec = &qs_msg;
recv_msg = send_recv_irm_msg(&msg);
-
if (recv_msg == NULL)
return -EIRMD;
@@ -1275,7 +1264,7 @@ int ipcp_flow_req_arr(pid_t pid,
return -1;
}
- fd = flow_init(recv_msg->port_id, recv_msg->pid, qc);
+ fd = flow_init(recv_msg->port_id, recv_msg->pid, qs);
irm_msg__free_unpacked(recv_msg, NULL);
@@ -1457,7 +1446,7 @@ int ipcp_flow_get_qoscube(int fd,
assert(ai.flows[fd].port_id >= 0);
- *cube = ai.flows[fd].cube;
+ *cube = qos_spec_to_cube(ai.flows[fd].spec);
pthread_rwlock_unlock(&ai.lock);
diff --git a/src/lib/frct.c b/src/lib/frct.c
index 516c958b..e9acb1dc 100644
--- a/src/lib/frct.c
+++ b/src/lib/frct.c
@@ -101,8 +101,7 @@ static void frct_fini(void)
timerwheel_destroy(frct.tw);
}
-static struct frcti * frcti_create(int fd,
- qoscube_t qc)
+static struct frcti * frcti_create(int fd)
{
struct frcti * frcti;
time_t delta_t;
@@ -133,7 +132,7 @@ static struct frcti * frcti_create(int fd,
frcti->snd_cr.inact = 3 * delta_t;
frcti->snd_cr.act = now.tv_sec - (frcti->snd_cr.inact + 1);
- if (qc == QOS_CUBE_DATA)
+ if (ai.flows[fd].spec.loss == 0)
frcti->snd_cr.cflags |= FRCTFRTX;
frcti->rcv_cr.inact = 2 * delta_t;
diff --git a/src/lib/ipcpd_messages.proto b/src/lib/ipcpd_messages.proto
index 454af0dc..48198a5b 100644
--- a/src/lib/ipcpd_messages.proto
+++ b/src/lib/ipcpd_messages.proto
@@ -23,6 +23,7 @@
syntax = "proto2";
import "ipcp_config.proto";
+import "qosspec.proto";
enum ipcp_msg_code {
IPCP_BOOTSTRAP = 1;
@@ -43,7 +44,7 @@ message ipcp_msg {
optional bytes hash = 2;
optional int32 port_id = 3;
optional string dst = 4;
- optional uint32 qoscube = 5;
+ optional qosspec_msg qosspec = 5;
optional ipcp_config_msg conf = 6;
optional int32 pid = 7;
optional layer_info_msg layer_info = 8;
diff --git a/src/lib/irmd_messages.proto b/src/lib/irmd_messages.proto
index 16dfe828..2ed2ec37 100644
--- a/src/lib/irmd_messages.proto
+++ b/src/lib/irmd_messages.proto
@@ -23,6 +23,7 @@
syntax = "proto2";
import "ipcp_config.proto";
+import "qosspec.proto";
enum irm_msg_code {
IRM_CREATE_IPCP = 1;
@@ -67,7 +68,7 @@ message irm_msg {
optional string dst = 9;
optional bytes hash = 10;
optional sint32 port_id = 11;
- optional sint32 qoscube = 12;
+ optional qosspec_msg qosspec = 12;
optional ipcp_config_msg conf = 13;
optional uint32 opts = 14;
repeated ipcp_info_msg ipcps = 15;
diff --git a/src/lib/qos.c b/src/lib/qos.c
index bee6ed71..8607031e 100644
--- a/src/lib/qos.c
+++ b/src/lib/qos.c
@@ -28,66 +28,61 @@
#include <string.h>
qosspec_t qos_raw = {
- .delay = UINT32_MAX,
- .bandwidth = 0,
- .availability = 0,
- .loss = 1,
- .in_order = 0,
- .maximum_interruption = UINT32_MAX
+ .delay = UINT32_MAX,
+ .bandwidth = 0,
+ .availability = 0,
+ .loss = 1,
+ .ber = 1,
+ .in_order = 0,
+ .max_gap = UINT32_MAX
+};
+
+qosspec_t qos_raw_no_errors = {
+ .delay = UINT32_MAX,
+ .bandwidth = 0,
+ .availability = 0,
+ .loss = 1,
+ .ber = 0,
+ .in_order = 0,
+ .max_gap = UINT32_MAX
};
qosspec_t qos_best_effort = {
- .delay = UINT32_MAX,
- .bandwidth = 0,
- .availability = 0,
- .loss = 1,
- .in_order = 1,
- .maximum_interruption = UINT32_MAX
+ .delay = UINT32_MAX,
+ .bandwidth = 0,
+ .availability = 0,
+ .loss = 1,
+ .ber = 0,
+ .in_order = 1,
+ .max_gap = UINT32_MAX
};
-qosspec_t qos_video = {
- .delay = 100,
- .bandwidth = UINT64_MAX,
- .availability = 3,
- .loss = 1,
- .in_order = 1,
- .maximum_interruption = 100
+qosspec_t qos_video = {
+ .delay = 100,
+ .bandwidth = UINT64_MAX,
+ .availability = 3,
+ .loss = 1,
+ .ber = 0,
+ .in_order = 1,
+ .max_gap = 100
};
qosspec_t qos_voice = {
- .delay = 50,
- .bandwidth = 100000,
- .availability = 5,
- .loss = 1,
- .in_order = 1,
- .maximum_interruption = 50
+ .delay = 50,
+ .bandwidth = 100000,
+ .availability = 5,
+ .loss = 1,
+ .ber = 0,
+ .in_order = 1,
+ .max_gap = 50
};
qosspec_t qos_data = {
- .delay = 1000,
- .bandwidth = 0,
- .availability = 0,
- .in_order = 1,
- .loss = 0,
- .maximum_interruption = 2000
+ .delay = 1000,
+ .bandwidth = 0,
+ .availability = 0,
+ .loss = 0,
+ .ber = 0,
+ .in_order = 1,
+ .max_gap = 2000
};
-
-int qosspec_init(qosspec_t * qs)
-{
- if (qs == NULL)
- return -EINVAL;
-
- *qs = qos_best_effort;
-
- return 0;
-}
-
-int qosspec_fini(qosspec_t * qs)
-{
- if (qs == NULL)
- return -EINVAL;
-
- memset(qs, 0, sizeof(*qs));
-
- return 0;
-}
diff --git a/src/lib/qoscube.c b/src/lib/qoscube.c
index 5dfa35ad..efca0e42 100644
--- a/src/lib/qoscube.c
+++ b/src/lib/qoscube.c
@@ -25,38 +25,20 @@
#include <string.h>
+
+
qoscube_t qos_spec_to_cube(qosspec_t qs)
{
- if (qs.loss == 0)
- return QOS_CUBE_DATA;
- else if (qs.delay <= qos_voice.delay &&
+ if (qs.delay <= qos_voice.delay &&
qs.bandwidth <= qos_voice.bandwidth &&
qs.availability >= qos_voice.availability &&
- qs.maximum_interruption <= qos_voice.maximum_interruption)
+ qs.max_gap <= qos_voice.max_gap)
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)
+ qs.max_gap <= qos_video.max_gap)
return QOS_CUBE_VIDEO;
- else if (qs.in_order == 1)
- return QOS_CUBE_BE;
else
- return QOS_CUBE_RAW;
-}
-
-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:
- return qos_best_effort;
- case QOS_CUBE_DATA:
- return qos_data;
- default:
- return qos_raw;
- }
+ return QOS_CUBE_BE;
}
diff --git a/src/lib/qosspec.proto b/src/lib/qosspec.proto
new file mode 100644
index 00000000..f355e345
--- /dev/null
+++ b/src/lib/qosspec.proto
@@ -0,0 +1,33 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2018
+ *
+ * QoS specification message
+ *
+ * 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., http://www.fsf.org/about/contact/.
+ */
+
+syntax = "proto2";
+
+message qosspec_msg {
+ required uint32 delay = 1; /* In ms */
+ required uint64 bandwidth = 2; /* In bits/s */
+ required uint32 availability = 3; /* Class of 9s */
+ required uint32 loss = 4; /* Packet loss */
+ required uint32 ber = 5; /* Bit error rate, ppb */
+ required uint32 in_order = 6; /* In-order delivery */
+ required uint32 max_gap = 7; /* In ms */
+};
diff --git a/src/lib/sockets.c b/src/lib/sockets.c
index b148b7ca..85726783 100644
--- a/src/lib/sockets.c
+++ b/src/lib/sockets.c
@@ -165,3 +165,38 @@ char * ipcp_sock_path(pid_t pid)
return full_name;
}
+
+qosspec_msg_t spec_to_msg(qosspec_t * qs)
+{
+ qosspec_t spec;
+ qosspec_msg_t msg = QOSSPEC_MSG__INIT;
+
+ spec = (qs == NULL ? qos_raw : *qs);
+
+ msg.delay = spec.delay;
+ msg.bandwidth = spec.bandwidth;
+ msg.availability = spec.availability;
+ msg.loss = spec.loss;
+ msg.ber = spec.ber;
+ msg.in_order = spec.in_order;
+ msg.max_gap = spec.max_gap;
+
+ return msg;
+}
+
+qosspec_t msg_to_spec(qosspec_msg_t * msg)
+{
+ qosspec_t spec;
+
+ assert(msg);
+
+ spec.delay = msg->delay;
+ spec.bandwidth = msg->bandwidth;
+ spec.availability = msg->availability;
+ spec.loss = msg->loss;
+ spec.ber = msg->ber;
+ spec.in_order = msg->in_order;
+ spec.max_gap = msg->max_gap;
+
+ return spec;
+}