diff options
Diffstat (limited to 'src/ipcpd/normal')
-rw-r--r-- | src/ipcpd/normal/pol/link_state.c | 53 |
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, ©); } @@ -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: |