summaryrefslogtreecommitdiff
path: root/src/ipcpd/normal
diff options
context:
space:
mode:
authorSander Vrijders <[email protected]>2018-07-12 17:31:07 +0200
committerDimitri Staessens <[email protected]>2018-07-15 11:25:58 +0200
commita3903da659e0f265f24628e65582e15ea25d4572 (patch)
treef23f15c5fc179aa042e2d8caa237660089327658 /src/ipcpd/normal
parent301212fc967b51fd01e02c0dca8c9183db923b11 (diff)
downloadouroboros-a3903da659e0f265f24628e65582e15ea25d4572.tar.gz
ouroboros-a3903da659e0f265f24628e65582e15ea25d4572.zip
ipcpd: Only forward new LSAs of the LSDB
This will add a sequence number to the Link State Advertisements so that upon receiving a LSA we can check if we need to forward the LSA or not. If we already have the LSA with the received seqno in the LSDB we do not forward it. This allows for setting up a management network that has loops since the spanning tree upon which the LSAs are sent is pruned on every hop. Signed-off-by: Sander Vrijders <[email protected]> Signed-off-by: Dimitri Staessens <[email protected]>
Diffstat (limited to 'src/ipcpd/normal')
-rw-r--r--src/ipcpd/normal/pol/link_state.c53
1 files changed, 36 insertions, 17 deletions
diff --git a/src/ipcpd/normal/pol/link_state.c b/src/ipcpd/normal/pol/link_state.c
index ac893432..8e5d3807 100644
--- a/src/ipcpd/normal/pol/link_state.c
+++ b/src/ipcpd/normal/pol/link_state.c
@@ -53,16 +53,21 @@
#define RECALC_TIME 4
#define LS_UPDATE_TIME 15
#define LS_TIMEO 60
-#define LS_ENTRY_SIZE 78
+#define LS_ENTRY_SIZE 104
#define LSDB "lsdb"
#ifndef CLOCK_REALTIME_COARSE
#define CLOCK_REALTIME_COARSE CLOCK_REALTIME
#endif
+#define LSA_NEW 0
+#define LSA_UPDATED 1
+#define LSA_OLD 2
+
struct lsa {
uint64_t d_addr;
uint64_t s_addr;
+ uint64_t seqno;
} __attribute__((packed));
struct routing_i {
@@ -82,6 +87,8 @@ struct adjacency {
uint64_t dst;
uint64_t src;
+ uint64_t seqno;
+
time_t stamp;
};
@@ -138,6 +145,7 @@ static int str_adj(struct adjacency * adj,
char tmbuf[64];
char srcbuf[64];
char dstbuf[64];
+ char seqnobuf[64];
struct tm * tm;
if (len < LS_ENTRY_SIZE)
@@ -148,9 +156,10 @@ static int str_adj(struct adjacency * adj,
sprintf(srcbuf, "%" PRIu64, adj->src);
sprintf(dstbuf, "%" PRIu64, adj->dst);
+ sprintf(seqnobuf, "%" PRIu64, adj->seqno);
- sprintf(buf, "src: %20s\ndst: %20s\nupd: %20s\n",
- srcbuf, dstbuf, tmbuf);
+ sprintf(buf, "src: %20s\ndst: %20s\nseqno: %18s\nupd: %20s\n",
+ srcbuf, dstbuf, seqnobuf, tmbuf);
return LS_ENTRY_SIZE;
}
@@ -386,11 +395,13 @@ static void set_pff_modified(void)
static int lsdb_add_link(uint64_t src,
uint64_t dst,
+ uint64_t seqno,
qosspec_t * qs)
{
struct list_head * p;
struct adjacency * adj;
struct timespec now;
+ int ret;
clock_gettime(CLOCK_REALTIME_COARSE, &now);
@@ -399,9 +410,11 @@ static int lsdb_add_link(uint64_t src,
list_for_each(p, &ls.db) {
struct adjacency * a = list_entry(p, struct adjacency, next);
if (a->dst == dst && a->src == src) {
+ ret = (a->seqno <= seqno ? LSA_OLD : LSA_UPDATED);
a->stamp = now.tv_sec;
+ a->seqno = seqno;
pthread_rwlock_unlock(&ls.db_lock);
- return 0;
+ return ret;
}
if (a->dst > dst || (a->dst == dst && a->src > src))
@@ -416,6 +429,7 @@ static int lsdb_add_link(uint64_t src,
adj->dst = dst;
adj->src = src;
+ adj->seqno = seqno;
adj->stamp = now.tv_sec;
list_add_tail(&adj->next, p);
@@ -429,7 +443,7 @@ static int lsdb_add_link(uint64_t src,
set_pff_modified();
- return 0;
+ return LSA_NEW;
}
static int lsdb_del_link(uint64_t src,
@@ -539,13 +553,15 @@ static void * periodic_recalc_pff(void * o)
}
static void send_lsm(uint64_t src,
- uint64_t dst)
+ uint64_t dst,
+ uint64_t seqno)
{
struct lsa lsm;
struct list_head * p;
lsm.d_addr = hton64(dst);
lsm.s_addr = hton64(src);
+ lsm.seqno = hton64(seqno);
list_for_each(p, &ls.nbs) {
struct nb * nb = list_entry(p, struct nb, next);
@@ -576,8 +592,9 @@ static void lsdb_replicate(int fd)
break;
}
- cpy->dst = adj->dst;
- cpy->src = adj->src;
+ cpy->dst = adj->dst;
+ cpy->src = adj->src;
+ cpy->seqno = adj->seqno;
list_add_tail(&cpy->next, &copy);
}
@@ -590,6 +607,7 @@ static void lsdb_replicate(int fd)
adj = list_entry(p, struct adjacency, next);
lsm.d_addr = hton64(adj->dst);
lsm.s_addr = hton64(adj->src);
+ lsm.seqno = hton64(adj->seqno);
list_del(&adj->next);
free(adj);
flow_write(fd, &lsm, sizeof(lsm));
@@ -627,7 +645,8 @@ static void * lsupdate(void * o)
}
if (adj->src == ipcpi.dt_addr) {
- send_lsm(adj->src, adj->dst);
+ adj->seqno++;
+ send_lsm(adj->src, adj->dst, adj->seqno);
adj->stamp = now.tv_sec;
}
}
@@ -716,11 +735,11 @@ static void * lsreader(void * o)
msg = (struct lsa *) buf;
- lsdb_add_link(ntoh64(msg->s_addr),
- ntoh64(msg->d_addr),
- &qs);
-
- forward_lsm(buf, len, fd);
+ if (lsdb_add_link(ntoh64(msg->s_addr),
+ ntoh64(msg->d_addr),
+ ntoh64(msg->seqno),
+ &qs) != LSA_OLD)
+ forward_lsm(buf, len, fd);
}
}
@@ -767,10 +786,10 @@ static void handle_event(void * self,
if (lsdb_add_nb(c->conn_info.addr, c->flow_info.fd, NB_DT))
log_dbg("Failed to add neighbor to LSDB.");
- if (lsdb_add_link(ipcpi.dt_addr, c->conn_info.addr, &qs))
- log_dbg("Failed to add adjacency to LSDB.");
+ if (lsdb_add_link(ipcpi.dt_addr, c->conn_info.addr, 0, &qs))
+ log_dbg("Failed to add new adjacency to LSDB.");
- send_lsm(ipcpi.dt_addr, c->conn_info.addr);
+ send_lsm(ipcpi.dt_addr, c->conn_info.addr, 0);
break;
case NOTIFY_DT_CONN_DEL: