diff options
Diffstat (limited to 'src/ipcpd')
-rw-r--r-- | src/ipcpd/normal/pol/link_state.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/src/ipcpd/normal/pol/link_state.c b/src/ipcpd/normal/pol/link_state.c index 179a3448..61469b94 100644 --- a/src/ipcpd/normal/pol/link_state.c +++ b/src/ipcpd/normal/pol/link_state.c @@ -528,13 +528,40 @@ static void send_lsm(uint64_t src, static void lsdb_replicate(int fd) { struct list_head * p; + struct list_head * h; + struct list_head copy; + + list_head_init(©); + + /* Lock the lsdb, copy the lsms and send outside of lock. */ + pthread_rwlock_rdlock(&ls.db_lock); list_for_each(p, &ls.db) { + struct adjacency * adj; + struct adjacency * cpy; + adj = list_entry(p, struct adjacency, next); + cpy = malloc(sizeof(*cpy)); + if (cpy == NULL) { + log_warn("Failed to replicate full lsdb."); + break; + } + + cpy->dst = adj->dst; + cpy->src = adj->src; + + list_add_tail(&cpy->next, ©); + } + + pthread_rwlock_unlock(&ls.db_lock); + + list_for_each_safe(p, h, ©) { struct lsa lsm; struct adjacency * adj; adj = list_entry(p, struct adjacency, next); lsm.d_addr = hton64(adj->dst); lsm.s_addr = hton64(adj->src); + list_del(&adj->next); + free(adj); flow_write(fd, &lsm, sizeof(lsm)); } } |