diff options
author | Ondrej Zajicek <santiago@crfreenet.org> | 2014-03-20 14:07:12 +0100 |
---|---|---|
committer | Ondrej Zajicek <santiago@crfreenet.org> | 2014-03-20 14:07:12 +0100 |
commit | 0c791f873aeb7c1052c97db7da4fe23873d69603 (patch) | |
tree | 48496c5965cb6e9f54d7863827c35054c3697c19 /sysdep/unix/krt.c | |
parent | 4e398e34bf140baf73fe8dceaf81078fb343f65a (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.c | 46 |
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; } |