summaryrefslogtreecommitdiff
path: root/sysdep/unix/krt.c
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2014-03-20 14:07:12 +0100
committerOndrej Zajicek <santiago@crfreenet.org>2014-03-20 14:07:12 +0100
commit0c791f873aeb7c1052c97db7da4fe23873d69603 (patch)
tree48496c5965cb6e9f54d7863827c35054c3697c19 /sysdep/unix/krt.c
parent4e398e34bf140baf73fe8dceaf81078fb343f65a (diff)
BGP graceful restart support.
Also significant core protocol state changes needed for that, global graceful restart recovery state and kernel proto support for recovery.
Diffstat (limited to 'sysdep/unix/krt.c')
-rw-r--r--sysdep/unix/krt.c46
1 files changed, 42 insertions, 4 deletions
diff --git a/sysdep/unix/krt.c b/sysdep/unix/krt.c
index 6fdef619..bff3001f 100644
--- a/sysdep/unix/krt.c
+++ b/sysdep/unix/krt.c
@@ -653,6 +653,13 @@ krt_got_route(struct krt_proto *p, rte *e)
return;
}
+ if (!p->ready)
+ {
+ /* We wait for the initial feed to have correct KRF_INSTALLED flag */
+ verdict = KRF_IGNORE;
+ goto sentenced;
+ }
+
old = net->routes;
if ((net->n.flags & KRF_INSTALLED) && rte_is_valid(old))
{
@@ -779,7 +786,9 @@ krt_prune(struct krt_proto *p)
if (KRT_CF->learn)
krt_learn_prune(p);
#endif
- p->initialized = 1;
+
+ if (p->ready)
+ p->initialized = 1;
}
void
@@ -852,7 +861,7 @@ krt_scan_timer_start(struct krt_proto *p)
krt_scan_count++;
- tm_start(krt_scan_timer, 0);
+ tm_start(krt_scan_timer, 1);
}
static void
@@ -867,6 +876,12 @@ krt_scan_timer_stop(struct krt_proto *p)
}
}
+static void
+krt_scan_timer_kick(struct krt_proto *p UNUSED)
+{
+ tm_start(krt_scan_timer, 0);
+}
+
#else
static void
@@ -885,7 +900,7 @@ static void
krt_scan_timer_start(struct krt_proto *p)
{
p->scan_timer = tm_new_set(p->p.pool, krt_scan, p, 0, KRT_CF->scan_time);
- tm_start(p->scan_timer, 0);
+ tm_start(p->scan_timer, 1);
}
static void
@@ -894,6 +909,12 @@ krt_scan_timer_stop(struct krt_proto *p)
tm_stop(p->scan_timer);
}
+static void
+krt_scan_timer_kick(struct krt_proto *p UNUSED)
+{
+ tm_start(p->scan_timer, 0);
+}
+
#endif
@@ -970,6 +991,16 @@ krt_notify(struct proto *P, struct rtable *table UNUSED, net *net,
krt_replace_rte(p, net, new, old, eattrs);
}
+static void
+krt_feed_done(struct proto *P)
+{
+ struct krt_proto *p = (struct krt_proto *) P;
+
+ p->ready = 1;
+ krt_scan_timer_kick(p);
+}
+
+
static int
krt_rte_same(rte *a, rte *b)
{
@@ -992,6 +1023,7 @@ krt_init(struct proto_config *c)
p->p.accept_ra_types = RA_OPTIMAL;
p->p.import_control = krt_import_control;
p->p.rt_notify = krt_notify;
+ p->p.feed_done = krt_feed_done;
p->p.make_tmp_attrs = krt_make_tmp_attrs;
p->p.store_tmp_attrs = krt_store_tmp_attrs;
p->p.rte_same = krt_rte_same;
@@ -1015,6 +1047,9 @@ krt_start(struct proto *P)
krt_scan_timer_start(p);
+ if (P->gr_recovery && KRT_CF->graceful_restart)
+ P->gr_wait = 1;
+
return PS_UP;
}
@@ -1029,6 +1064,9 @@ krt_shutdown(struct proto *P)
if (p->initialized && !KRT_CF->persist)
krt_flush_routes(p);
+ p->ready = 0;
+ p->initialized = 0;
+
krt_sys_shutdown(p);
rem_node(&p->krt_node);
@@ -1045,7 +1083,7 @@ krt_reconfigure(struct proto *p, struct proto_config *new)
if (!krt_sys_reconfigure((struct krt_proto *) p, n, o))
return 0;
- /* persist needn't be the same */
+ /* persist, graceful restart need not be the same */
return o->scan_time == n->scan_time && o->learn == n->learn && o->devroutes == n->devroutes;
}