0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-23 10:11:53 +00:00

Merge commit 'a0b176e3b2b50d3a30574afa927e0ee8ef65be68' into integrated

This commit is contained in:
Ondrej Zajicek 2013-07-31 18:36:26 +02:00
commit ed5c7b636e
6 changed files with 50 additions and 24 deletions

View File

@ -836,14 +836,18 @@ static void
proto_schedule_flush_loop(void) proto_schedule_flush_loop(void)
{ {
struct proto *p; struct proto *p;
struct announce_hook *h;
if (flush_loop_state) if (flush_loop_state)
return; return;
flush_loop_state = 1; flush_loop_state = 1;
rt_schedule_prune_all();
WALK_LIST(p, flush_proto_list) WALK_LIST(p, flush_proto_list)
{
p->flushing = 1; p->flushing = 1;
for (h=p->ahooks; h; h=h->next)
h->table->prune_state = 1;
}
ev_schedule(proto_flush_event); ev_schedule(proto_flush_event);
} }

View File

@ -161,7 +161,7 @@ typedef struct rtable {
int gc_counter; /* Number of operations since last GC */ int gc_counter; /* Number of operations since last GC */
bird_clock_t gc_time; /* Time of last GC */ bird_clock_t gc_time; /* Time of last GC */
byte gc_scheduled; /* GC is scheduled */ byte gc_scheduled; /* GC is scheduled */
byte prune_state; /* Table prune state, 1 -> prune is running */ byte prune_state; /* Table prune state, 1 -> scheduled, 2-> running */
byte hcu_scheduled; /* Hostcache update is scheduled */ byte hcu_scheduled; /* Hostcache update is scheduled */
byte nhu_state; /* Next Hop Update state */ byte nhu_state; /* Next Hop Update state */
struct fib_iterator prune_fit; /* Rtable prune FIB iterator */ struct fib_iterator prune_fit; /* Rtable prune FIB iterator */
@ -307,7 +307,6 @@ void rt_dump(rtable *);
void rt_dump_all(void); void rt_dump_all(void);
int rt_feed_baby(struct proto *p); int rt_feed_baby(struct proto *p);
void rt_feed_baby_abort(struct proto *p); void rt_feed_baby_abort(struct proto *p);
void rt_schedule_prune_all(void);
int rt_prune_loop(void); int rt_prune_loop(void);
struct rtable_config *rt_new_table(struct symbol *s, int addr_type); struct rtable_config *rt_new_table(struct symbol *s, int addr_type);
static inline int rt_match(int rt, u32 rtlist) { return !rtlist || ((1 << rt) & rtlist); } static inline int rt_match(int rt, u32 rtlist) { return !rtlist || ((1 << rt) & rtlist); }

View File

@ -1332,19 +1332,8 @@ rt_init(void)
} }
/* Called from proto_schedule_flush_loop() only,
ensuring that all prune states are zero */
void
rt_schedule_prune_all(void)
{
rtable *t;
WALK_LIST(t, routing_tables)
t->prune_state = 1;
}
static inline int static inline int
rt_prune_step(rtable *tab, int *max_feed) rt_prune_step(rtable *tab, int step, int *max_feed)
{ {
struct fib_iterator *fit = &tab->prune_fit; struct fib_iterator *fit = &tab->prune_fit;
@ -1370,8 +1359,8 @@ again:
rescan: rescan:
for (e=n->routes; e; e=e->next) for (e=n->routes; e; e=e->next)
if (e->sender->proto->core_state != FS_HAPPY && if (e->sender->proto->flushing ||
e->sender->proto->core_state != FS_FEEDING) (step && e->attrs->proto->flushing))
{ {
if (*max_feed <= 0) if (*max_feed <= 0)
{ {
@ -1379,6 +1368,10 @@ again:
return 0; return 0;
} }
if (step)
log(L_WARN "Route %I/%d from %s still in %s after flush",
n->n.prefix, n->n.pxlen, e->attrs->proto->name, tab->name);
rte_discard(tab, e); rte_discard(tab, e);
(*max_feed)--; (*max_feed)--;
@ -1403,23 +1396,42 @@ again:
/** /**
* rt_prune_loop - prune routing tables * rt_prune_loop - prune routing tables
* @tab: routing table to be pruned
* *
* The prune loop scans routing tables and removes routes belonging to * The prune loop scans routing tables and removes routes belonging to
* inactive protocols and also stale network entries. Returns 1 when * flushing protocols and also stale network entries. Returns 1 when
* all such routes are pruned. It is a part of the protocol flushing * all such routes are pruned. It is a part of the protocol flushing
* loop. * loop.
*
* The prune loop runs in two steps. In the first step it prunes just
* the routes with flushing senders (in explicitly marked tables) so
* the route removal is propagated as usual. In the second step, all
* remaining relevant routes are removed. Ideally, there shouldn't be
* any, but it happens when pipe filters are changed.
*/ */
int int
rt_prune_loop(void) rt_prune_loop(void)
{ {
rtable *t; static int step = 0;
int max_feed = 512; int max_feed = 512;
rtable *t;
again:
WALK_LIST(t, routing_tables) WALK_LIST(t, routing_tables)
if (! rt_prune_step(t, &max_feed)) if (! rt_prune_step(t, step, &max_feed))
return 0; return 0;
if (step == 0)
{
/* Prepare for the second step */
WALK_LIST(t, routing_tables)
t->prune_state = 1;
step = 1;
goto again;
}
/* Done */
step = 0;
return 1; return 1;
} }

View File

@ -384,10 +384,12 @@ bgp_conn_enter_close_state(struct bgp_conn *conn)
int os = conn->state; int os = conn->state;
bgp_conn_set_state(conn, BS_CLOSE); bgp_conn_set_state(conn, BS_CLOSE);
tm_stop(conn->hold_timer);
tm_stop(conn->keepalive_timer); tm_stop(conn->keepalive_timer);
conn->sk->rx_hook = NULL; conn->sk->rx_hook = NULL;
/* Timeout for CLOSE state, if we cannot send notification soon then we just hangup */
bgp_start_timer(conn->hold_timer, 10);
if (os == BS_ESTABLISHED) if (os == BS_ESTABLISHED)
bgp_conn_leave_established_state(p); bgp_conn_leave_established_state(p);
} }
@ -478,9 +480,18 @@ static void
bgp_hold_timeout(timer *t) bgp_hold_timeout(timer *t)
{ {
struct bgp_conn *conn = t->data; struct bgp_conn *conn = t->data;
struct bgp_proto *p = conn->bgp;
DBG("BGP: Hold timeout\n"); DBG("BGP: Hold timeout\n");
/* We are already closing the connection - just do hangup */
if (conn->state == BS_CLOSE)
{
BGP_TRACE(D_EVENTS, "Connection stalled");
bgp_conn_enter_idle_state(conn);
return;
}
/* If there is something in input queue, we are probably congested /* If there is something in input queue, we are probably congested
and perhaps just not processed BGP packets in time. */ and perhaps just not processed BGP packets in time. */

View File

@ -395,7 +395,7 @@ static void
radv_err_hook(sock *sk, int err) radv_err_hook(sock *sk, int err)
{ {
struct radv_iface *ifa = sk->data; struct radv_iface *ifa = sk->data;
log(L_ERR "%s: Socket error: %m", ifa->ra->p.name, err); log(L_ERR "%s: Socket error on %s: %M", ifa->ra->p.name, ifa->iface->name, err);
} }
int int

View File

@ -17,10 +17,10 @@
#include <sys/time.h> #include <sys/time.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/fcntl.h>
#include <sys/uio.h> #include <sys/uio.h>
#include <sys/un.h> #include <sys/un.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h>
#include <errno.h> #include <errno.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <netinet/icmp6.h> #include <netinet/icmp6.h>