mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 09:41:54 +00:00
Several minor fixes
This commit is contained in:
parent
ed1d853e51
commit
7fc55925be
@ -2044,6 +2044,7 @@ avoid routing loops.
|
|||||||
<item> <rfc id="7911"> - Advertisement of Multiple Paths in BGP
|
<item> <rfc id="7911"> - Advertisement of Multiple Paths in BGP
|
||||||
<item> <rfc id="7947"> - Internet Exchange BGP Route Server
|
<item> <rfc id="7947"> - Internet Exchange BGP Route Server
|
||||||
<item> <rfc id="8092"> - BGP Large Communities Attribute
|
<item> <rfc id="8092"> - BGP Large Communities Attribute
|
||||||
|
<item> <rfc id="8203"> - BGP Administrative Shutdown Communication
|
||||||
</itemize>
|
</itemize>
|
||||||
|
|
||||||
<sect1>Route selection rules
|
<sect1>Route selection rules
|
||||||
@ -2258,6 +2259,20 @@ using the following configuration parameters:
|
|||||||
related procedures. Note that even when disabled, BIRD can send route
|
related procedures. Note that even when disabled, BIRD can send route
|
||||||
refresh requests. Default: on.
|
refresh requests. Default: on.
|
||||||
|
|
||||||
|
<tag><label id="bgp-graceful-restart">graceful restart <m/switch/|aware</tag>
|
||||||
|
When a BGP speaker restarts or crashes, neighbors will discard all
|
||||||
|
received paths from the speaker, which disrupts packet forwarding even
|
||||||
|
when the forwarding plane of the speaker remains intact. <rfc id="4724">
|
||||||
|
specifies an optional graceful restart mechanism to alleviate this
|
||||||
|
issue. This option controls the mechanism. It has three states:
|
||||||
|
Disabled, when no support is provided. Aware, when the graceful restart
|
||||||
|
support is announced and the support for restarting neighbors is
|
||||||
|
provided, but no local graceful restart is allowed (i.e. receiving-only
|
||||||
|
role). Enabled, when the full graceful restart support is provided
|
||||||
|
(i.e. both restarting and receiving role). Restarting role could be also
|
||||||
|
configured per-channel. Note that proper support for local graceful
|
||||||
|
restart requires also configuration of other protocols. Default: aware.
|
||||||
|
|
||||||
<tag><label id="bgp-graceful-restart-time">graceful restart time <m/number/</tag>
|
<tag><label id="bgp-graceful-restart-time">graceful restart time <m/number/</tag>
|
||||||
The restart time is announced in the BGP graceful restart capability
|
The restart time is announced in the BGP graceful restart capability
|
||||||
and specifies how long the neighbor would wait for the BGP session to
|
and specifies how long the neighbor would wait for the BGP session to
|
||||||
@ -2487,19 +2502,12 @@ together with their appropriate channels follows.
|
|||||||
TX direction. When active, all available routes accepted by the export
|
TX direction. When active, all available routes accepted by the export
|
||||||
filter are advertised to the neighbor. Default: off.
|
filter are advertised to the neighbor. Default: off.
|
||||||
|
|
||||||
<tag><label id="bgp-graceful-restart">graceful restart <m/switch/|aware</tag>
|
<tag><label id="bgp-graceful-restart-c">graceful restart <m/switch/</tag>
|
||||||
When a BGP speaker restarts or crashes, neighbors will discard all
|
Although BGP graceful restart is configured mainly by protocol-wide
|
||||||
received paths from the speaker, which disrupts packet forwarding even
|
<ref id="bgp-graceful-restart" name="options">, it is possible to
|
||||||
when the forwarding plane of the speaker remains intact. <rfc
|
configure restarting role per AFI/SAFI pair by this channel option.
|
||||||
id="4724"> specifies an optional graceful restart mechanism to
|
The option is ignored if graceful restart is disabled by protocol-wide
|
||||||
alleviate this issue. This option controls the mechanism. It has three
|
option. Default: off in aware mode, on in full mode.
|
||||||
states: Disabled, when no support is provided. Aware, when the graceful
|
|
||||||
restart support is announced and the support for restarting neighbors
|
|
||||||
is provided, but no local graceful restart is allowed (i.e.
|
|
||||||
receiving-only role). Enabled, when the full graceful restart
|
|
||||||
support is provided (i.e. both restarting and receiving role). Note
|
|
||||||
that proper support for local graceful restart requires also
|
|
||||||
configuration of other protocols. Default: aware.
|
|
||||||
</descrip>
|
</descrip>
|
||||||
|
|
||||||
<sect1>Attributes
|
<sect1>Attributes
|
||||||
|
@ -230,11 +230,14 @@ static inline int net_type_match(const net_addr *a, u32 mask)
|
|||||||
static inline int net_is_ip(const net_addr *a)
|
static inline int net_is_ip(const net_addr *a)
|
||||||
{ return (a->type == NET_IP4) || (a->type == NET_IP6); }
|
{ return (a->type == NET_IP4) || (a->type == NET_IP6); }
|
||||||
|
|
||||||
|
static inline int net_is_vpn(const net_addr *a)
|
||||||
|
{ return (a->type == NET_VPN4) || (a->type == NET_VPN6); }
|
||||||
|
|
||||||
static inline int net_is_roa(const net_addr *a)
|
static inline int net_is_roa(const net_addr *a)
|
||||||
{ return (a->type == NET_ROA4) || (a->type == NET_ROA6); }
|
{ return (a->type == NET_ROA4) || (a->type == NET_ROA6); }
|
||||||
|
|
||||||
static inline int net_is_vpn(const net_addr *a)
|
static inline int net_is_flow(const net_addr *a)
|
||||||
{ return (a->type == NET_VPN4) || (a->type == NET_VPN6); }
|
{ return (a->type == NET_FLOW4) || (a->type == NET_FLOW6); }
|
||||||
|
|
||||||
|
|
||||||
static inline ip4_addr net4_prefix(const net_addr *a)
|
static inline ip4_addr net4_prefix(const net_addr *a)
|
||||||
|
@ -849,7 +849,7 @@ if_show(void)
|
|||||||
else if (i->master_index)
|
else if (i->master_index)
|
||||||
bsprintf(mbuf, " master=#%u", i->master_index);
|
bsprintf(mbuf, " master=#%u", i->master_index);
|
||||||
|
|
||||||
cli_msg(-1001, "%s %s (index=%d%s)", i->name, (i->flags & IF_UP) ? "Up" : "Down", i->index, mbuf);
|
cli_msg(-1001, "%s %s (index=%d%s)", i->name, (i->flags & IF_UP) ? "up" : "down", i->index, mbuf);
|
||||||
if (!(i->flags & IF_MULTIACCESS))
|
if (!(i->flags & IF_MULTIACCESS))
|
||||||
type = "PtP";
|
type = "PtP";
|
||||||
else
|
else
|
||||||
@ -897,7 +897,7 @@ if_show_summary(void)
|
|||||||
a6[0] = 0;
|
a6[0] = 0;
|
||||||
|
|
||||||
cli_msg(-1005, "%-10s %-6s %-18s %s",
|
cli_msg(-1005, "%-10s %-6s %-18s %s",
|
||||||
i->name, (i->flags & IF_UP) ? "Up" : "Down", a4, a6);
|
i->name, (i->flags & IF_UP) ? "up" : "down", a4, a6);
|
||||||
}
|
}
|
||||||
cli_msg(0, "");
|
cli_msg(0, "");
|
||||||
}
|
}
|
||||||
|
@ -897,7 +897,9 @@ rte_validate(rte *e)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
c = net_classify(n->n.addr);
|
/* FIXME: better handling different nettypes */
|
||||||
|
c = !net_is_flow(n->n.addr) ?
|
||||||
|
net_classify(n->n.addr): (IADDR_HOST | SCOPE_UNIVERSE);
|
||||||
if ((c < 0) || !(c & IADDR_HOST) || ((c & IADDR_SCOPE_MASK) <= SCOPE_LINK))
|
if ((c < 0) || !(c & IADDR_HOST) || ((c & IADDR_SCOPE_MASK) <= SCOPE_LINK))
|
||||||
{
|
{
|
||||||
log(L_WARN "Ignoring bogus route %N received via %s",
|
log(L_WARN "Ignoring bogus route %N received via %s",
|
||||||
|
@ -64,8 +64,6 @@
|
|||||||
* format - Optional hook that converts eattr to textual representation.
|
* format - Optional hook that converts eattr to textual representation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// XXXX review pool usage : c->c.proto->pool
|
|
||||||
|
|
||||||
|
|
||||||
struct bgp_attr_desc {
|
struct bgp_attr_desc {
|
||||||
const char *name;
|
const char *name;
|
||||||
@ -1175,6 +1173,22 @@ bgp_init_bucket_table(struct bgp_channel *c)
|
|||||||
c->withdraw_bucket = NULL;
|
c->withdraw_bucket = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
bgp_free_bucket_table(struct bgp_channel *c)
|
||||||
|
{
|
||||||
|
HASH_FREE(c->bucket_hash);
|
||||||
|
|
||||||
|
struct bgp_bucket *b;
|
||||||
|
WALK_LIST_FIRST(b, c->bucket_queue)
|
||||||
|
{
|
||||||
|
rem_node(&b->send_node);
|
||||||
|
mb_free(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
mb_free(c->withdraw_bucket);
|
||||||
|
c->withdraw_bucket = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static struct bgp_bucket *
|
static struct bgp_bucket *
|
||||||
bgp_get_bucket(struct bgp_channel *c, ea_list *new)
|
bgp_get_bucket(struct bgp_channel *c, ea_list *new)
|
||||||
{
|
{
|
||||||
|
@ -98,6 +98,7 @@
|
|||||||
* <item> <rfc id="7911"> - Advertisement of Multiple Paths in BGP
|
* <item> <rfc id="7911"> - Advertisement of Multiple Paths in BGP
|
||||||
* <item> <rfc id="7947"> - Internet Exchange BGP Route Server
|
* <item> <rfc id="7947"> - Internet Exchange BGP Route Server
|
||||||
* <item> <rfc id="8092"> - BGP Large Communities Attribute
|
* <item> <rfc id="8092"> - BGP Large Communities Attribute
|
||||||
|
* <item> <rfc id="8203"> - BGP Administrative Shutdown Communication
|
||||||
* </itemize>
|
* </itemize>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -601,10 +602,6 @@ bgp_conn_leave_established_state(struct bgp_proto *p)
|
|||||||
BGP_TRACE(D_EVENTS, "BGP session closed");
|
BGP_TRACE(D_EVENTS, "BGP session closed");
|
||||||
p->conn = NULL;
|
p->conn = NULL;
|
||||||
|
|
||||||
// XXXX free these tables to avoid memory leak during graceful restart
|
|
||||||
// bgp_free_prefix_table(p);
|
|
||||||
// bgp_free_bucket_table(p);
|
|
||||||
|
|
||||||
if (p->p.proto_state == PS_UP)
|
if (p->p.proto_state == PS_UP)
|
||||||
bgp_stop(p, 0, NULL, 0);
|
bgp_stop(p, 0, NULL, 0);
|
||||||
}
|
}
|
||||||
@ -664,6 +661,10 @@ bgp_handle_graceful_restart(struct bgp_proto *p)
|
|||||||
struct bgp_channel *c;
|
struct bgp_channel *c;
|
||||||
WALK_LIST(c, p->p.channels)
|
WALK_LIST(c, p->p.channels)
|
||||||
{
|
{
|
||||||
|
/* FIXME: perhaps check for channel state instead of disabled flag? */
|
||||||
|
if (c->c.disabled)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (c->gr_ready)
|
if (c->gr_ready)
|
||||||
{
|
{
|
||||||
if (c->gr_active)
|
if (c->gr_active)
|
||||||
@ -679,6 +680,13 @@ bgp_handle_graceful_restart(struct bgp_proto *p)
|
|||||||
rt_refresh_begin(c->c.table, &c->c);
|
rt_refresh_begin(c->c.table, &c->c);
|
||||||
rt_refresh_end(c->c.table, &c->c);
|
rt_refresh_end(c->c.table, &c->c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Reset bucket and prefix tables */
|
||||||
|
bgp_free_bucket_table(c);
|
||||||
|
bgp_free_prefix_table(c);
|
||||||
|
bgp_init_bucket_table(c);
|
||||||
|
bgp_init_prefix_table(c);
|
||||||
|
c->packets_to_send = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
proto_notify_state(&p->p, PS_START);
|
proto_notify_state(&p->p, PS_START);
|
||||||
@ -1315,7 +1323,7 @@ bgp_start(struct proto *P)
|
|||||||
p->source_addr = p->cf->local_ip;
|
p->source_addr = p->cf->local_ip;
|
||||||
p->link_addr = IPA_NONE;
|
p->link_addr = IPA_NONE;
|
||||||
|
|
||||||
/* XXXX */
|
/* Lock all channels when in GR recovery mode */
|
||||||
if (p->p.gr_recovery && p->cf->gr_mode)
|
if (p->p.gr_recovery && p->cf->gr_mode)
|
||||||
{
|
{
|
||||||
struct bgp_channel *c;
|
struct bgp_channel *c;
|
||||||
@ -1546,10 +1554,9 @@ bgp_channel_shutdown(struct channel *C)
|
|||||||
{
|
{
|
||||||
struct bgp_channel *c = (void *) C;
|
struct bgp_channel *c = (void *) C;
|
||||||
|
|
||||||
/* XXXX: cleanup bucket and prefix tables */
|
|
||||||
|
|
||||||
c->next_hop_addr = IPA_NONE;
|
c->next_hop_addr = IPA_NONE;
|
||||||
c->link_addr = IPA_NONE;
|
c->link_addr = IPA_NONE;
|
||||||
|
c->packets_to_send = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -2064,17 +2071,12 @@ bgp_show_proto_info(struct proto *P)
|
|||||||
bgp_show_capabilities(p, p->conn->local_caps);
|
bgp_show_capabilities(p, p->conn->local_caps);
|
||||||
cli_msg(-1006, " Neighbor capabilities");
|
cli_msg(-1006, " Neighbor capabilities");
|
||||||
bgp_show_capabilities(p, p->conn->remote_caps);
|
bgp_show_capabilities(p, p->conn->remote_caps);
|
||||||
/* XXXX
|
cli_msg(-1006, " Session: %s%s%s%s%s",
|
||||||
cli_msg(-1006, " Session: %s%s%s%s%s%s%s%s",
|
|
||||||
p->is_internal ? "internal" : "external",
|
p->is_internal ? "internal" : "external",
|
||||||
p->cf->multihop ? " multihop" : "",
|
p->cf->multihop ? " multihop" : "",
|
||||||
p->rr_client ? " route-reflector" : "",
|
p->rr_client ? " route-reflector" : "",
|
||||||
p->rs_client ? " route-server" : "",
|
p->rs_client ? " route-server" : "",
|
||||||
p->as4_session ? " AS4" : "",
|
p->as4_session ? " AS4" : "");
|
||||||
p->add_path_rx ? " add-path-rx" : "",
|
|
||||||
p->add_path_tx ? " add-path-tx" : "",
|
|
||||||
p->ext_messages ? " ext-messages" : "");
|
|
||||||
*/
|
|
||||||
cli_msg(-1006, " Source address: %I", p->source_addr);
|
cli_msg(-1006, " Source address: %I", p->source_addr);
|
||||||
cli_msg(-1006, " Hold timer: %t/%u",
|
cli_msg(-1006, " Hold timer: %t/%u",
|
||||||
tm_remains(p->conn->hold_timer), p->conn->hold_time);
|
tm_remains(p->conn->hold_timer), p->conn->hold_time);
|
||||||
@ -2091,16 +2093,18 @@ bgp_show_proto_info(struct proto *P)
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
/* XXXX ?? */
|
|
||||||
struct bgp_channel *c;
|
struct bgp_channel *c;
|
||||||
WALK_LIST(c, p->p.channels)
|
WALK_LIST(c, p->p.channels)
|
||||||
{
|
{
|
||||||
channel_show_info(&c->c);
|
channel_show_info(&c->c);
|
||||||
|
|
||||||
|
if (c->c.channel_state == CS_UP)
|
||||||
|
{
|
||||||
if (ipa_zero(c->link_addr))
|
if (ipa_zero(c->link_addr))
|
||||||
cli_msg(-1006, " BGP Next hop: %I", c->next_hop_addr);
|
cli_msg(-1006, " BGP Next hop: %I", c->next_hop_addr);
|
||||||
else
|
else
|
||||||
cli_msg(-1006, " BGP Next hop: %I %I", c->next_hop_addr, c->link_addr);
|
cli_msg(-1006, " BGP Next hop: %I %I", c->next_hop_addr, c->link_addr);
|
||||||
|
}
|
||||||
|
|
||||||
if (c->igp_table_ip4)
|
if (c->igp_table_ip4)
|
||||||
cli_msg(-1006, " IGP IPv4 table: %s", c->igp_table_ip4->name);
|
cli_msg(-1006, " IGP IPv4 table: %s", c->igp_table_ip4->name);
|
||||||
|
@ -492,11 +492,13 @@ int bgp_encode_attrs(struct bgp_write_state *s, ea_list *attrs, byte *buf, byte
|
|||||||
ea_list * bgp_decode_attrs(struct bgp_parse_state *s, byte *data, uint len);
|
ea_list * bgp_decode_attrs(struct bgp_parse_state *s, byte *data, uint len);
|
||||||
|
|
||||||
void bgp_init_bucket_table(struct bgp_channel *c);
|
void bgp_init_bucket_table(struct bgp_channel *c);
|
||||||
|
void bgp_free_bucket_table(struct bgp_channel *c);
|
||||||
void bgp_free_bucket(struct bgp_channel *c, struct bgp_bucket *b);
|
void bgp_free_bucket(struct bgp_channel *c, struct bgp_bucket *b);
|
||||||
void bgp_defer_bucket(struct bgp_channel *c, struct bgp_bucket *b);
|
void bgp_defer_bucket(struct bgp_channel *c, struct bgp_bucket *b);
|
||||||
void bgp_withdraw_bucket(struct bgp_channel *c, struct bgp_bucket *b);
|
void bgp_withdraw_bucket(struct bgp_channel *c, struct bgp_bucket *b);
|
||||||
|
|
||||||
void bgp_init_prefix_table(struct bgp_channel *c);
|
void bgp_init_prefix_table(struct bgp_channel *c);
|
||||||
|
void bgp_free_prefix_table(struct bgp_channel *c);
|
||||||
void bgp_free_prefix(struct bgp_channel *c, struct bgp_prefix *bp);
|
void bgp_free_prefix(struct bgp_channel *c, struct bgp_prefix *bp);
|
||||||
|
|
||||||
int bgp_rte_better(struct rte *, struct rte *);
|
int bgp_rte_better(struct rte *, struct rte *);
|
||||||
|
@ -1637,8 +1637,8 @@ bgp_decode_nlri_flow4(struct bgp_parse_state *s, byte *pos, uint len, rta *a)
|
|||||||
uint pxlen = data[1];
|
uint pxlen = data[1];
|
||||||
|
|
||||||
// FIXME: Use some generic function
|
// FIXME: Use some generic function
|
||||||
memcpy(&px, data, BYTES(pxlen));
|
memcpy(&px, data+2, BYTES(pxlen));
|
||||||
px = ip4_and(px, ip4_mkmask(pxlen));
|
px = ip4_and(ip4_ntoh(px), ip4_mkmask(pxlen));
|
||||||
|
|
||||||
/* Prepare the flow */
|
/* Prepare the flow */
|
||||||
net_addr *n = alloca(sizeof(struct net_addr_flow4) + flen);
|
net_addr *n = alloca(sizeof(struct net_addr_flow4) + flen);
|
||||||
@ -1729,8 +1729,8 @@ bgp_decode_nlri_flow6(struct bgp_parse_state *s, byte *pos, uint len, rta *a)
|
|||||||
uint pxlen = data[1];
|
uint pxlen = data[1];
|
||||||
|
|
||||||
// FIXME: Use some generic function
|
// FIXME: Use some generic function
|
||||||
memcpy(&px, data, BYTES(pxlen));
|
memcpy(&px, data+2, BYTES(pxlen));
|
||||||
px = ip6_and(px, ip6_mkmask(pxlen));
|
px = ip6_and(ip6_ntoh(px), ip6_mkmask(pxlen));
|
||||||
|
|
||||||
/* Prepare the flow */
|
/* Prepare the flow */
|
||||||
net_addr *n = alloca(sizeof(struct net_addr_flow6) + flen);
|
net_addr *n = alloca(sizeof(struct net_addr_flow6) + flen);
|
||||||
|
@ -499,7 +499,7 @@ CF_ADDTO(dynamic_attr, OSPF_TAG { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEM
|
|||||||
CF_ADDTO(dynamic_attr, OSPF_ROUTER_ID { $$ = f_new_dynamic_attr(EAF_TYPE_ROUTER_ID | EAF_TEMP, T_QUAD, EA_OSPF_ROUTER_ID); })
|
CF_ADDTO(dynamic_attr, OSPF_ROUTER_ID { $$ = f_new_dynamic_attr(EAF_TYPE_ROUTER_ID | EAF_TEMP, T_QUAD, EA_OSPF_ROUTER_ID); })
|
||||||
|
|
||||||
CF_CLI_HELP(SHOW OSPF, ..., [[Show information about OSPF protocol]]);
|
CF_CLI_HELP(SHOW OSPF, ..., [[Show information about OSPF protocol]]);
|
||||||
CF_CLI(SHOW OSPF, optsym, [<name>], [[Show information about OSPF protocol XXX]])
|
CF_CLI(SHOW OSPF, optsym, [<name>], [[Show information about OSPF protocol]])
|
||||||
{ ospf_sh(proto_get_named($3, &proto_ospf)); };
|
{ ospf_sh(proto_get_named($3, &proto_ospf)); };
|
||||||
|
|
||||||
CF_CLI(SHOW OSPF NEIGHBORS, optsym opttext, [<name>] [\"<interface>\"], [[Show information about OSPF neighbors]])
|
CF_CLI(SHOW OSPF NEIGHBORS, optsym opttext, [<name>] [\"<interface>\"], [[Show information about OSPF neighbors]])
|
||||||
|
Loading…
Reference in New Issue
Block a user