summaryrefslogtreecommitdiff
path: root/src/ipcpd/normal/pol/link_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ipcpd/normal/pol/link_state.c')
-rw-r--r--src/ipcpd/normal/pol/link_state.c76
1 files changed, 72 insertions, 4 deletions
diff --git a/src/ipcpd/normal/pol/link_state.c b/src/ipcpd/normal/pol/link_state.c
index 51d317bc..f3af2771 100644
--- a/src/ipcpd/normal/pol/link_state.c
+++ b/src/ipcpd/normal/pol/link_state.c
@@ -62,8 +62,10 @@ typedef LinkStateMsg link_state_msg_t;
#endif
struct routing_i {
- struct pff * pff;
- pthread_t calculator;
+ struct list_head next;
+
+ struct pff * pff;
+ pthread_t calculator;
};
/* TODO: link weight support. */
@@ -89,6 +91,10 @@ struct nb {
enum nb_type type;
};
+typedef int (* rtable_fn_t)(struct graph * graph,
+ uint64_t s_addr,
+ struct list_head * table);
+
struct {
struct list_head nbs;
fset_t * mgmt_set;
@@ -103,6 +109,11 @@ struct {
pthread_t lsupdate;
pthread_t lsreader;
pthread_t listener;
+
+ struct list_head routing_instances;
+ pthread_mutex_t routing_i_lock;
+
+ rtable_fn_t rtable;
} ls;
struct pol_routing_ops link_state_ops = {
@@ -388,7 +399,7 @@ static void * calculate_pff(void * o)
instance = (struct routing_i *) o;
while (true) {
- if (graph_routing_table(ls.graph, ipcpi.dt_addr, &table)) {
+ if (ls.rtable(ls.graph, ipcpi.dt_addr, &table)) {
sleep(RECALC_TIME);
continue;
}
@@ -584,6 +595,24 @@ static void * lsreader(void * o)
return (void *) 0;
}
+static void flow_event(int fd,
+ bool up)
+{
+
+ struct list_head * p;
+
+ log_dbg("Notifying routing instances of flow event.");
+
+ pthread_mutex_lock(&ls.routing_i_lock);
+
+ list_for_each(p, &ls.routing_instances) {
+ struct routing_i * ri = list_entry(p, struct routing_i, next);
+ pff_flow_state_change(ri->pff, fd, up);
+ }
+
+ pthread_mutex_unlock(&ls.routing_i_lock);
+}
+
static void handle_event(void * self,
int event,
const void * o)
@@ -608,6 +637,8 @@ static void handle_event(void * self,
send_lsm(ipcpi.dt_addr, c->conn_info.addr);
break;
case NOTIFY_DT_CONN_DEL:
+ flow_event(c->flow_info.fd, false);
+
if (lsdb_del_nb(c->conn_info.addr, c->flow_info.fd))
log_dbg("Failed to delete neighbor from LSDB.");
@@ -617,6 +648,12 @@ static void handle_event(void * self,
case NOTIFY_DT_CONN_QOS:
log_dbg("QoS changes currently unsupported.");
break;
+ case NOTIFY_DT_CONN_UP:
+ flow_event(c->flow_info.fd, true);
+ break;
+ case NOTIFY_DT_CONN_DOWN:
+ flow_event(c->flow_info.fd, false);
+ break;
case NOTIFY_MGMT_CONN_ADD:
fset_add(ls.mgmt_set, c->flow_info.fd);
if (lsdb_add_nb(c->conn_info.addr, c->flow_info.fd, NB_MGMT))
@@ -650,6 +687,12 @@ struct routing_i * link_state_routing_i_create(struct pff * pff)
return NULL;
}
+ pthread_mutex_lock(&ls.routing_i_lock);
+
+ list_add(&tmp->next, &ls.routing_instances);
+
+ pthread_mutex_unlock(&ls.routing_i_lock);
+
return tmp;
}
@@ -657,6 +700,12 @@ void link_state_routing_i_destroy(struct routing_i * instance)
{
assert(instance);
+ pthread_mutex_lock(&ls.routing_i_lock);
+
+ list_del(&instance->next);
+
+ pthread_mutex_unlock(&ls.routing_i_lock);
+
pthread_cancel(instance->calculator);
pthread_join(instance->calculator, NULL);
@@ -664,7 +713,7 @@ void link_state_routing_i_destroy(struct routing_i * instance)
free(instance);
}
-int link_state_init(void)
+int link_state_init(enum pol_routing pr)
{
struct conn_info info;
@@ -676,6 +725,17 @@ int link_state_init(void)
info.pref_syntax = PROTO_GPB;
info.addr = ipcpi.dt_addr;
+ switch (pr) {
+ case ROUTING_LINK_STATE:
+ ls.rtable = graph_routing_table;
+ break;
+ case ROUTING_LINK_STATE_LFA:
+ ls.rtable = graph_routing_table_lfa;
+ break;
+ default:
+ goto fail_graph;
+ }
+
ls.graph = graph_create();
if (ls.graph == NULL)
goto fail_graph;
@@ -686,6 +746,9 @@ int link_state_init(void)
if (pthread_rwlock_init(&ls.db_lock, NULL))
goto fail_db_lock_init;
+ if (pthread_mutex_init(&ls.routing_i_lock, NULL))
+ goto fail_routing_i_lock_init;
+
if (connmgr_ae_init(AEID_MGMT, &info))
goto fail_connmgr_ae_init;
@@ -695,6 +758,7 @@ int link_state_init(void)
list_head_init(&ls.db);
list_head_init(&ls.nbs);
+ list_head_init(&ls.routing_instances);
if (pthread_create(&ls.lsupdate, NULL, lsupdate, NULL))
goto fail_pthread_create_lsupdate;
@@ -722,6 +786,8 @@ int link_state_init(void)
fail_fset_create:
connmgr_ae_fini(AEID_MGMT);
fail_connmgr_ae_init:
+ pthread_mutex_destroy(&ls.routing_i_lock);
+ fail_routing_i_lock_init:
pthread_rwlock_destroy(&ls.db_lock);
fail_db_lock_init:
notifier_unreg(handle_event);
@@ -765,5 +831,7 @@ void link_state_fini(void)
pthread_rwlock_destroy(&ls.db_lock);
+ pthread_mutex_destroy(&ls.routing_i_lock);
+
notifier_unreg(handle_event);
}