summaryrefslogtreecommitdiff
path: root/src/ipcpd/unicast
diff options
context:
space:
mode:
authorDimitri Staessens <dimitri@ouroboros.rocks>2026-06-14 16:00:30 +0200
committerSander Vrijders <sander@ouroboros.rocks>2026-06-29 08:32:58 +0200
commitc386d9b7caa56f472fdce20ff5b2841ed41dd539 (patch)
tree81c8124854e0557ef6be4d9eda0a15f28f79350a /src/ipcpd/unicast
parent22e2380b09730a2f18deefd688585edb430d3299 (diff)
downloadouroboros-c386d9b7caa56f472fdce20ff5b2841ed41dd539.tar.gz
ouroboros-c386d9b7caa56f472fdce20ff5b2841ed41dd539.zip
ipcpd: Add flow-update relay
This adds an ipcp_flow_update() call to relay opaque messages between the two IRMds (carried by FLOW_IRM_UPDATE messages), which passes it back up to the peer IRMd via ipcp_flow_update_arr(). The broadcast layer does not implement this. Needed for periodic re-keying of encrypted flows via OAP. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
Diffstat (limited to 'src/ipcpd/unicast')
-rw-r--r--src/ipcpd/unicast/fa.c87
-rw-r--r--src/ipcpd/unicast/fa.h3
-rw-r--r--src/ipcpd/unicast/main.c3
3 files changed, 89 insertions, 4 deletions
diff --git a/src/ipcpd/unicast/fa.c b/src/ipcpd/unicast/fa.c
index 43c56f90..c6eca175 100644
--- a/src/ipcpd/unicast/fa.c
+++ b/src/ipcpd/unicast/fa.c
@@ -37,6 +37,7 @@
#include <ouroboros/errno.h>
#include <ouroboros/dev.h>
#include <ouroboros/ipcp-dev.h>
+#include <ouroboros/np1_flow.h>
#include <ouroboros/rib.h>
#include <ouroboros/random.h>
#include <ouroboros/pthread.h>
@@ -61,9 +62,10 @@
#define TIMEOUT 10 * MILLION /* nanoseconds */
#define MSGBUFSZ 32768
-#define FLOW_REQ 0
-#define FLOW_REPLY 1
-#define FLOW_UPDATE 2
+#define FLOW_REQ 0
+#define FLOW_REPLY 1
+#define FLOW_UPDATE 2
+#define FLOW_IRM_UPDATE 3
#define STAT_FILE_LEN 0
@@ -585,6 +587,43 @@ static int fa_handle_flow_update(struct fa_msg * msg,
return 0;
}
+static int fa_handle_flow_irm_update(struct fa_msg * msg,
+ size_t len)
+{
+ buffer_t data;
+ int fd;
+ int flow_id;
+
+ if (len < sizeof(*msg))
+ return -EINVAL;
+
+ data.data = (uint8_t *) msg + sizeof(*msg);
+ data.len = len - sizeof(*msg);
+
+ pthread_rwlock_rdlock(&fa.flows_lock);
+
+ fd = eid_to_fd(ntoh64(msg->r_eid));
+
+ pthread_rwlock_unlock(&fa.flows_lock);
+
+ if (fd < 0) {
+ log_err("Flow update for unknown EID %" PRIu64 ".",
+ ntoh64(msg->r_eid));
+ return -ENOTALLOC;
+ }
+
+ flow_id = np1_flow_id(fd);
+ if (flow_id < 0)
+ return -ENOTALLOC;
+
+ if (ipcp_flow_update_arr(flow_id, &data) < 0) {
+ log_err("Failed to relay flow update on fd %d.", fd);
+ return -EIRMD;
+ }
+
+ return 0;
+}
+
static void * fa_handle_packet(void * o)
{
(void) o;
@@ -613,6 +652,10 @@ static void * fa_handle_packet(void * o)
if (fa_handle_flow_update(msg, len) < 0)
log_err("Error handling flow update.");
break;
+ case FLOW_IRM_UPDATE:
+ if (fa_handle_flow_irm_update(msg, len) < 0)
+ log_err("Error handling flow update.");
+ break;
default:
log_warn("Recieved unknown flow allocation message.");
break;
@@ -872,6 +915,44 @@ int fa_alloc_resp(int fd,
return -1;
}
+int fa_irm_update(int fd,
+ const buffer_t * data)
+{
+ struct fa_msg * msg;
+ struct ssm_pk_buff * spb;
+ struct fa_flow * flow;
+ qoscube_t qc = QOS_CUBE_BE;
+ uint64_t r_addr;
+
+ flow = &fa.flows[fd];
+
+ if (ipcp_spb_reserve(&spb, sizeof(*msg) + data->len))
+ return -1;
+
+ msg = (struct fa_msg *) ssm_pk_buff_head(spb);
+ memset(msg, 0, sizeof(*msg));
+
+ msg->code = FLOW_IRM_UPDATE;
+ if (data->len > 0)
+ memcpy(msg + 1, data->data, data->len);
+
+ pthread_rwlock_rdlock(&fa.flows_lock);
+
+ msg->r_eid = hton64(flow->r_eid);
+ msg->s_eid = hton64(flow->s_eid);
+ r_addr = flow->r_addr;
+
+ pthread_rwlock_unlock(&fa.flows_lock);
+
+ if (dt_write_packet(r_addr, qc, fa.eid, spb)) {
+ log_err("Failed to send flow update packet.");
+ ipcp_spb_release(spb);
+ return -1;
+ }
+
+ return 0;
+}
+
int fa_dealloc(int fd)
{
if (ipcp_flow_fini(fd) < 0)
diff --git a/src/ipcpd/unicast/fa.h b/src/ipcpd/unicast/fa.h
index 0c19dc25..f31b40e9 100644
--- a/src/ipcpd/unicast/fa.h
+++ b/src/ipcpd/unicast/fa.h
@@ -45,6 +45,9 @@ int fa_alloc_resp(int fd,
int fa_dealloc(int fd);
+int fa_irm_update(int fd,
+ const buffer_t * data);
+
void fa_np1_rcv(uint64_t eid,
uint8_t ecn,
struct ssm_pk_buff * spb);
diff --git a/src/ipcpd/unicast/main.c b/src/ipcpd/unicast/main.c
index 9a35531e..1155b88b 100644
--- a/src/ipcpd/unicast/main.c
+++ b/src/ipcpd/unicast/main.c
@@ -273,7 +273,8 @@ static struct ipcp_ops unicast_ops = {
.ipcp_flow_alloc = fa_alloc,
.ipcp_flow_join = NULL,
.ipcp_flow_alloc_resp = fa_alloc_resp,
- .ipcp_flow_dealloc = fa_dealloc
+ .ipcp_flow_dealloc = fa_dealloc,
+ .ipcp_flow_update = fa_irm_update
};
int main(int argc,