diff options
| -rw-r--r-- | include/ouroboros/ipcp-dev.h | 2 | ||||
| -rw-r--r-- | include/ouroboros/np1_flow.h | 2 | ||||
| -rw-r--r-- | include/ouroboros/qos.h | 22 | ||||
| -rw-r--r-- | include/ouroboros/sockets.h.in | 11 | ||||
| -rw-r--r-- | src/ipcpd/eth/eth.c | 51 | ||||
| -rw-r--r-- | src/ipcpd/ipcp.c | 13 | ||||
| -rw-r--r-- | src/ipcpd/ipcp.h | 2 | ||||
| -rw-r--r-- | src/ipcpd/local/main.c | 4 | ||||
| -rw-r--r-- | src/ipcpd/normal/dt.c | 2 | ||||
| -rw-r--r-- | src/ipcpd/normal/fa.c | 57 | ||||
| -rw-r--r-- | src/ipcpd/normal/fa.h | 2 | ||||
| -rw-r--r-- | src/ipcpd/raptor/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/ipcpd/raptor/main.c | 77 | ||||
| -rw-r--r-- | src/ipcpd/udp/main.c | 48 | ||||
| -rw-r--r-- | src/irmd/ipcp.c | 13 | ||||
| -rw-r--r-- | src/irmd/ipcp.h | 2 | ||||
| -rw-r--r-- | src/irmd/irm_flow.c | 4 | ||||
| -rw-r--r-- | src/irmd/irm_flow.h | 5 | ||||
| -rw-r--r-- | src/irmd/main.c | 22 | ||||
| -rw-r--r-- | src/lib/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | src/lib/dev.c | 87 | ||||
| -rw-r--r-- | src/lib/frct.c | 5 | ||||
| -rw-r--r-- | src/lib/ipcpd_messages.proto | 3 | ||||
| -rw-r--r-- | src/lib/irmd_messages.proto | 3 | ||||
| -rw-r--r-- | src/lib/qos.c | 97 | ||||
| -rw-r--r-- | src/lib/qoscube.c | 30 | ||||
| -rw-r--r-- | src/lib/qosspec.proto | 33 | ||||
| -rw-r--r-- | src/lib/sockets.c | 35 | 
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(ð_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; +}  | 
