struct timeformat tf_log; /* Time format for the logfile */
struct timeformat tf_base; /* Time format for other purposes */
u32 gr_wait; /* Graceful restart wait timeout (sec) */
- const char *hostname; /* Hostname */
int cli_debug; /* Tracing of CLI connections and commands */
- int latency_debug; /* I/O loop tracks duration of each event */
+ enum latency_debug_flags {
+ DL_PING = 1,
+ DL_WAKEUP = 2,
+ DL_SCHEDULING = 4,
+ DL_ALLOCATOR = 8,
+ DL_SOCKETS = 0x10,
+ DL_EVENTS = 0x20,
+ DL_TIMERS = 0x40,
+ } latency_debug; /* I/O loops log information about task scheduling */
u32 latency_limit; /* Events with longer duration are logged (us) */
u32 watchdog_warning; /* I/O loop watchdog limit for warning (us) */
u32 watchdog_timeout; /* Watchdog timeout (in seconds, 0 = disabled) */
| DEBUG debug_mask { this_proto->debug = $2; }
| MRTDUMP mrtdump_mask { this_proto->mrtdump = $2; }
| ROUTER ID idval { this_proto->router_id = $3; }
+ | HOSTNAME text { this_proto->hostname = $2; }
| DESCRIPTION text { this_proto->dsc = $2; }
- | VRF text { this_proto->vrf = if_get_by_name($2); this_proto->vrf_set = 1; }
- | VRF DEFAULT { this_proto->vrf = NULL; this_proto->vrf_set = 1; }
+ | VRF text { this_proto->vrf = if_get_by_name($2); }
+ | VRF DEFAULT { this_proto->vrf = &default_vrf; }
;
int class; /* SYM_PROTO or SYM_TEMPLATE */
u8 net_type; /* Protocol network type (NET_*), 0 for undefined */
u8 disabled; /* Protocol enabled/disabled by default */
- u8 vrf_set; /* Related VRF instance (below) is defined */
+ u8 late_if_feed; /* Delay interface feed after channels are up */
u32 debug, mrtdump; /* Debugging bitfields, both use D_* constants */
u32 router_id; /* Protocol specific router ID */
+ const char *hostname; /* Protocol specific hostname */
+ uint loop_order; /* Launch a birdloop on this locking level; use DOMAIN_ORDER(the_bird) for mainloop */
+ btime loop_max_latency; /* Request this specific maximum latency of loop; zero to default */
+ btime restart_limit; /* Minimum allowed time between limit restarts */
list channels; /* List of channel configs (struct channel_config) */
struct iface *vrf; /* Related VRF instance, NULL if global */
static inline u32
proto_get_router_id(struct proto_config *pc)
{
- return pc->router_id ? pc->router_id : pc->global->router_id;
+ return pc->router_id ?: atomic_load_explicit(&global_runtime, memory_order_relaxed)->router_id;
}
+ static inline const char*
+ proto_get_hostname(struct proto_config *pc)
+ {
+ return pc->hostname ? pc->hostname : pc->global->hostname;
+ }
+
extern pool *proto_pool;
-extern list proto_list;
/*
* Each protocol instance runs two different state machines:
cli_msg(-1006, " BGP Next hop: %I %I", c->next_hop_addr, c->link_addr);
}
- if (c->igp_table_ip4)
- cli_msg(-1006, " IGP IPv4 table: %s", c->igp_table_ip4->name);
+ /* After channel is deconfigured, these pointers are no longer valid */
+ if (!p->p.reconfiguring || (c->c.channel_state != CS_DOWN))
+ {
+ if (c->igp_table_ip4)
+ cli_msg(-1006, " IGP IPv4 table: %s", c->igp_table_ip4->name);
- if (c->igp_table_ip6)
- cli_msg(-1006, " IGP IPv6 table: %s", c->igp_table_ip6->name);
+ if (c->igp_table_ip6)
+ cli_msg(-1006, " IGP IPv6 table: %s", c->igp_table_ip6->name);
- if (c->base_table)
- cli_msg(-1006, " Base table: %s", c->base_table->name);
+ if (c->base_table)
+ cli_msg(-1006, " Base table: %s", c->base_table->name);
+ }
+
+ if (!c->tx)
+ continue;
+
+ BGP_PTX_LOCK(c->tx, tx);
+
+ uint bucket_cnt = 0;
+ uint prefix_cnt = 0;
+ struct bgp_bucket *buck;
+ struct bgp_prefix *px;
+ WALK_LIST(buck, tx->bucket_queue)
+ {
+ bucket_cnt++;
+ WALK_LIST(px, buck->prefixes)
+ if (px->cur)
+ prefix_cnt++;
+ }
+
+ cli_msg(-1006, " Pending %u attribute sets with total %u prefixes to send",
+ bucket_cnt, prefix_cnt);
}
}
}