Link state support in BGP.
Configurable fast shutdown of a BGP session when an interface loses link.
This commit is contained in:
parent
7730553b7e
commit
523f020b5f
4 changed files with 83 additions and 47 deletions
|
@ -316,20 +316,20 @@ protocol rip {
|
|||
<sect>Global options
|
||||
|
||||
<p><descrip>
|
||||
<tag>include "<m/filename/"</tag>
|
||||
<tag>include "<m/filename/"</tag>
|
||||
This statement causes inclusion of a new file. <m/Filename/ could also
|
||||
be a wildcard. The maximal depth is 8. Note that this statement could be
|
||||
used anywhere in the config file, not just as a top-level option.
|
||||
|
||||
<tag><label id="dsc-log">log "<m/filename/"|syslog [name <m/name/]|stderr all|{ <m/list of classes/ }</tag>
|
||||
<tag><label id="dsc-log">log "<m/filename/"|syslog [name <m/name/]|stderr all|{ <m/list of classes/ }</tag>
|
||||
Set logging of messages having the given class (either <cf/all/ or
|
||||
<cf/{ error, trace }/ etc.) into selected destination (a file specified
|
||||
as a filename string, syslog with optional name argument, or the stderr
|
||||
output). Classes are:
|
||||
<cf/info/, <cf/warning/, <cf/error/ and <cf/fatal/ for messages about local problems,
|
||||
<cf/debug/ for debugging messages,
|
||||
<cf/trace/ when you want to know what happens in the network,
|
||||
<cf/remote/ for messages about misbehavior of remote machines,
|
||||
<cf/debug/ for debugging messages,
|
||||
<cf/trace/ when you want to know what happens in the network,
|
||||
<cf/remote/ for messages about misbehavior of remote machines,
|
||||
<cf/auth/ about authentication failures,
|
||||
<cf/bug/ for internal BIRD bugs.
|
||||
You may specify more than one <cf/log/ line to establish logging to
|
||||
|
@ -358,7 +358,7 @@ protocol rip {
|
|||
|
||||
<tag>function <m/name/ (<m/parameters/) <m/local variables/ { <m/commands/ }</tag>
|
||||
Define a function. You can learn more about functions in the following chapter.
|
||||
|
||||
|
||||
<tag>protocol rip|ospf|bgp|... [<m/name/ [from <m/name2/]] { <m>protocol options</m> }</tag>
|
||||
Define a protocol instance called <cf><m/name/</cf> (or with a name like
|
||||
"rip5" generated automatically if you don't specify any
|
||||
|
@ -508,7 +508,7 @@ agreement").
|
|||
This option can be used to override global router id for a given
|
||||
protocol. Default: uses global router id.
|
||||
|
||||
<tag>import all | none | filter <m/name/ | filter { <m/filter commands/ } | where <m/filter expression/</tag>
|
||||
<tag>import all | none | filter <m/name/ | filter { <m/filter commands/ } | where <m/filter expression/</tag>
|
||||
Specify a filter to be used for filtering routes coming from the
|
||||
protocol to the routing table. <cf/all/ is shorthand for <cf/where true/
|
||||
and <cf/none/ is shorthand for <cf/where false/. Default: <cf/all/.
|
||||
|
@ -586,7 +586,7 @@ agreement").
|
|||
An interface option can be used more times with different interface-specific
|
||||
options, in that case for given interface the first matching interface
|
||||
option is used.
|
||||
|
||||
|
||||
This option is allowed in BFD, Direct, OSPF, RAdv and RIP protocols, but
|
||||
in OSPF protocol it is used in the <cf/area/ subsection.
|
||||
|
||||
|
@ -599,7 +599,7 @@ agreement").
|
|||
|
||||
<cf>interface "eth1", "eth4", "eth5" { type ptp; };</cf> - start the
|
||||
protocol on enumerated interfaces with <cf>type ptp</cf> option.
|
||||
|
||||
|
||||
<cf>interface -192.168.1.0/24, 192.168.0.0/16;</cf> - start the protocol
|
||||
on all interfaces that have address from 192.168.0.0/16, but not from
|
||||
192.168.1.0/24.
|
||||
|
@ -632,7 +632,7 @@ agreement").
|
|||
used. Specifying passwords does not mean that authentication is enabled,
|
||||
authentication can be enabled by separate, protocol-dependent
|
||||
<cf/authentication/ option.
|
||||
|
||||
|
||||
This option is allowed in OSPF and RIP protocols. BGP has also
|
||||
<cf/password/ option, but it is slightly different and described
|
||||
separately.
|
||||
|
@ -1085,7 +1085,7 @@ foot).
|
|||
is true, but <cf>1.0.0.0/16 ˜ [ 1.0.0.0/8- ]</cf> is false.
|
||||
|
||||
Cisco-style patterns like <cf>10.0.0.0/8 ge 16 le 24</cf> can be expressed
|
||||
in BIRD as <cf>10.0.0.0/8{16,24}</cf>, <cf>192.168.0.0/16 le 24</cf> as
|
||||
in BIRD as <cf>10.0.0.0/8{16,24}</cf>, <cf>192.168.0.0/16 le 24</cf> as
|
||||
<cf>192.168.0.0/16{16,24}</cf> and <cf>192.168.0.0/16 ge 24</cf> as
|
||||
<cf>192.168.0.0/16{24,32}</cf>.
|
||||
|
||||
|
@ -1129,7 +1129,7 @@ foot).
|
|||
˜ [= 2 3 5 * =]</cf> syntax). The masks resemble wildcard patterns
|
||||
as used by UNIX shells. Autonomous system numbers match themselves,
|
||||
<cf/*/ matches any (even empty) sequence of arbitrary AS numbers and
|
||||
<cf/?/ matches one arbitrary AS number. For example, if <cf>bgp_path</cf>
|
||||
<cf/?/ matches one arbitrary AS number. For example, if <cf>bgp_path</cf>
|
||||
is 4 3 2 1, then: <tt>bgp_path ˜ [= * 4 3 * =]</tt> is true,
|
||||
but <tt>bgp_path ˜ [= * 4 5 * =]</tt> is false. BGP mask
|
||||
expressions can also contain integer expressions enclosed in parenthesis
|
||||
|
@ -1206,7 +1206,7 @@ prefix and an ASN as arguments.
|
|||
|
||||
<sect>Control structures
|
||||
|
||||
<p>Filters support two control structures: conditions and case switches.
|
||||
<p>Filters support two control structures: conditions and case switches.
|
||||
|
||||
<p>Syntax of a condition is: <cf>if <M>boolean expression</M> then <m/command1/;
|
||||
else <m/command2/;</cf> and you can use <cf>{ <m/command_1/; <m/command_2/;
|
||||
|
@ -1232,9 +1232,9 @@ case arg1 {
|
|||
else: print "something else";
|
||||
}
|
||||
|
||||
if 1234 = i then printn "."; else {
|
||||
print "not 1234";
|
||||
print "You need {} around multiple commands";
|
||||
if 1234 = i then printn "."; else {
|
||||
print "not 1234";
|
||||
print "You need {} around multiple commands";
|
||||
}
|
||||
</code>
|
||||
|
||||
|
@ -1267,7 +1267,7 @@ clist for most purposes.
|
|||
|
||||
<tag><m/ip/ from</tag>
|
||||
The router which the route has originated from.
|
||||
|
||||
|
||||
<tag><m/ip/ gw</tag>
|
||||
Next hop packets routed using this route should be forwarded to.
|
||||
|
||||
|
@ -1448,7 +1448,7 @@ protocol bfd [<name>] {
|
|||
BFD sessions are usually created on demand as requested by other
|
||||
protocols (like OSPF or BGP). This option allows to explicitly add
|
||||
a BFD session to the specified neighbor regardless of such requests.
|
||||
|
||||
|
||||
The session is identified by the IP address of the neighbor, with
|
||||
optional specification of used interface and local IP. By default
|
||||
the neighbor must be directly connected, unless the the session is
|
||||
|
@ -1559,13 +1559,13 @@ MD5 password authentication
|
|||
(RFC 2385<htmlurl url="ftp://ftp.rfc-editor.org/in-notes/rfc2385.txt">),
|
||||
extended communities
|
||||
(RFC 4360<htmlurl url="ftp://ftp.rfc-editor.org/in-notes/rfc4360.txt">),
|
||||
route reflectors
|
||||
route reflectors
|
||||
(RFC 4456<htmlurl url="ftp://ftp.rfc-editor.org/in-notes/rfc4456.txt">),
|
||||
graceful restart
|
||||
(RFC 4724<htmlurl url="ftp://ftp.rfc-editor.org/in-notes/rfc4724.txt">),
|
||||
multiprotocol extensions
|
||||
(RFC 4760<htmlurl url="ftp://ftp.rfc-editor.org/in-notes/rfc4760.txt">),
|
||||
4B AS numbers
|
||||
4B AS numbers
|
||||
(RFC 4893<htmlurl url="ftp://ftp.rfc-editor.org/in-notes/rfc4893.txt">),
|
||||
and 4B AS numbers in extended communities
|
||||
(RFC 5668<htmlurl url="ftp://ftp.rfc-editor.org/in-notes/rfc5668.txt">).
|
||||
|
@ -1691,6 +1691,13 @@ using the following configuration parameters:
|
|||
Specifies a table that is used as an IGP routing table. Default: the
|
||||
same as the table BGP is connected to.
|
||||
|
||||
<tag>check link <M>switch</M></tag>
|
||||
BGP could use hardware link state into consideration. If enabled,
|
||||
BIRD tracks the link state of the associated interface and when link
|
||||
disappears (e.g. an ethernet cable is unplugged), the BGP session is
|
||||
immediately shut down. Note that this option cannot be used with
|
||||
multihop BGP. Default: disabled.
|
||||
|
||||
<tag>bfd <M>switch</M></tag>
|
||||
BGP could use BFD protocol as an advisory mechanism for neighbor
|
||||
liveness and failure detection. If enabled, BIRD setups a BFD session
|
||||
|
@ -1709,7 +1716,7 @@ using the following configuration parameters:
|
|||
(IPv4), 2.6.35+ (IPv6), BSD: since long ago, IPv4 only. Note that full
|
||||
(ICMP protection, for example) RFC 5082 support is provided by Linux
|
||||
only. Default: disabled.
|
||||
|
||||
|
||||
<tag>password <m/string/</tag>
|
||||
Use this password for MD5 authentication of BGP sessions. Default: no
|
||||
authentication. Password has to be set by external utility
|
||||
|
@ -1732,7 +1739,7 @@ using the following configuration parameters:
|
|||
id. Clients in a cluster need not know their cluster id and this option
|
||||
is not allowed for them. Default: the same as router id.
|
||||
|
||||
<tag>rs client</tag>
|
||||
<tag>rs client</tag>
|
||||
Be a route server and treat the neighbor as a route server client.
|
||||
A route server is used as a replacement for full mesh EBGP routing in
|
||||
Internet exchange points in a similar way to route reflectors used in
|
||||
|
@ -1760,7 +1767,7 @@ using the following configuration parameters:
|
|||
TX direction. When active, all available routes accepted by the export
|
||||
filter are advertised to the neighbor. Default: off.
|
||||
|
||||
<tag>allow local as [<m/number/]</tag>
|
||||
<tag>allow local as [<m/number/]</tag>
|
||||
BGP prevents routing loops by rejecting received routes with the local
|
||||
AS number in the AS path. This option allows to loose or disable the
|
||||
check. Optional <cf/number/ argument can be used to specify the maximum
|
||||
|
|
|
@ -366,7 +366,7 @@ void
|
|||
bgp_conn_enter_established_state(struct bgp_conn *conn)
|
||||
{
|
||||
struct bgp_proto *p = conn->bgp;
|
||||
|
||||
|
||||
BGP_TRACE(D_EVENTS, "BGP session established");
|
||||
DBG("BGP: UP!!!\n");
|
||||
|
||||
|
@ -828,7 +828,7 @@ bgp_start_neighbor(struct bgp_proto *p)
|
|||
/* Called only for single-hop BGP sessions */
|
||||
|
||||
if (ipa_zero(p->source_addr))
|
||||
p->source_addr = p->neigh->ifa->ip;
|
||||
p->source_addr = p->neigh->ifa->ip;
|
||||
|
||||
#ifdef IPV6
|
||||
{
|
||||
|
@ -855,25 +855,43 @@ static void
|
|||
bgp_neigh_notify(neighbor *n)
|
||||
{
|
||||
struct bgp_proto *p = (struct bgp_proto *) n->proto;
|
||||
int ps = p->p.proto_state;
|
||||
|
||||
if (! (n->flags & NEF_STICKY))
|
||||
if (n != p->neigh)
|
||||
return;
|
||||
|
||||
if (n->scope > 0)
|
||||
if ((ps == PS_DOWN) || (ps == PS_STOP))
|
||||
return;
|
||||
|
||||
int prepare = (ps == PS_START) && (p->start_state == BSS_PREPARE);
|
||||
|
||||
if (n->scope <= 0)
|
||||
{
|
||||
if ((p->p.proto_state == PS_START) && (p->start_state == BSS_PREPARE))
|
||||
{
|
||||
BGP_TRACE(D_EVENTS, "Neighbor found");
|
||||
bgp_start_neighbor(p);
|
||||
if (!prepare)
|
||||
{
|
||||
BGP_TRACE(D_EVENTS, "Neighbor lost");
|
||||
bgp_store_error(p, NULL, BE_MISC, BEM_NEIGHBOR_LOST);
|
||||
/* Perhaps also run bgp_update_startup_delay(p)? */
|
||||
bgp_stop(p, 0);
|
||||
}
|
||||
}
|
||||
else if (p->cf->check_link && !(n->iface->flags & IF_LINK_UP))
|
||||
{
|
||||
if (!prepare)
|
||||
{
|
||||
BGP_TRACE(D_EVENTS, "Link down");
|
||||
bgp_store_error(p, NULL, BE_MISC, BEM_LINK_DOWN);
|
||||
if (ps == PS_UP)
|
||||
bgp_update_startup_delay(p);
|
||||
bgp_stop(p, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((p->p.proto_state == PS_START) || (p->p.proto_state == PS_UP))
|
||||
if (prepare)
|
||||
{
|
||||
BGP_TRACE(D_EVENTS, "Neighbor lost");
|
||||
bgp_store_error(p, NULL, BE_MISC, BEM_NEIGHBOR_LOST);
|
||||
bgp_stop(p, 0);
|
||||
BGP_TRACE(D_EVENTS, "Neighbor ready");
|
||||
bgp_start_neighbor(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -952,8 +970,8 @@ bgp_start_locked(struct object_lock *lock)
|
|||
return;
|
||||
}
|
||||
|
||||
p->neigh = neigh_find2(&p->p, &cf->remote_ip, cf->iface, NEF_STICKY);
|
||||
if (!p->neigh || (p->neigh->scope == SCOPE_HOST))
|
||||
neighbor *n = neigh_find2(&p->p, &cf->remote_ip, cf->iface, NEF_STICKY);
|
||||
if (!n)
|
||||
{
|
||||
log(L_ERR "%s: Invalid remote address %I%J", p->p.name, cf->remote_ip, cf->iface);
|
||||
/* As we do not start yet, we can just disable protocol */
|
||||
|
@ -962,11 +980,15 @@ bgp_start_locked(struct object_lock *lock)
|
|||
proto_notify_state(&p->p, PS_DOWN);
|
||||
return;
|
||||
}
|
||||
|
||||
if (p->neigh->scope > 0)
|
||||
bgp_start_neighbor(p);
|
||||
else
|
||||
|
||||
p->neigh = n;
|
||||
|
||||
if (n->scope <= 0)
|
||||
BGP_TRACE(D_EVENTS, "Waiting for %I%J to become my neighbor", cf->remote_ip, cf->iface);
|
||||
else if (p->cf->check_link && !(n->iface->flags & IF_LINK_UP))
|
||||
BGP_TRACE(D_EVENTS, "Waiting for link on %s", n->iface->name);
|
||||
else
|
||||
bgp_start_neighbor(p);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -1173,6 +1195,9 @@ bgp_check_config(struct bgp_config *c)
|
|||
ipa_is_link_local(c->source_addr)))
|
||||
cf_error("Multihop BGP cannot be used with link-local addresses");
|
||||
|
||||
if (c->multihop && c->check_link)
|
||||
cf_error("Multihop BGP cannot depend on link state");
|
||||
|
||||
if (c->multihop && c->bfd && ipa_zero(c->source_addr))
|
||||
cf_error("Multihop BGP with BFD requires specified source address");
|
||||
|
||||
|
@ -1288,7 +1313,7 @@ bgp_store_error(struct bgp_proto *p, struct bgp_conn *c, u8 class, u32 code)
|
|||
|
||||
static char *bgp_state_names[] = { "Idle", "Connect", "Active", "OpenSent", "OpenConfirm", "Established", "Close" };
|
||||
static char *bgp_err_classes[] = { "", "Error: ", "Socket: ", "Received: ", "BGP Error: ", "Automatic shutdown: ", ""};
|
||||
static char *bgp_misc_errors[] = { "", "Neighbor lost", "Invalid next hop", "Kernel MD5 auth failed", "No listening socket", "BFD session down", "Graceful restart"};
|
||||
static char *bgp_misc_errors[] = { "", "Neighbor lost", "Invalid next hop", "Kernel MD5 auth failed", "No listening socket", "Link down", "BFD session down", "Graceful restart"};
|
||||
static char *bgp_auto_errors[] = { "", "Route limit exceeded"};
|
||||
|
||||
static const char *
|
||||
|
@ -1396,7 +1421,7 @@ bgp_show_proto_info(struct proto *P)
|
|||
tm_remains(c->keepalive_timer), c->keepalive_time);
|
||||
}
|
||||
|
||||
if ((p->last_error_class != BE_NONE) &&
|
||||
if ((p->last_error_class != BE_NONE) &&
|
||||
(p->last_error_class != BE_MAN_DOWN))
|
||||
{
|
||||
const char *err1 = bgp_err_classes[p->last_error_class];
|
||||
|
|
|
@ -62,6 +62,7 @@ struct bgp_config {
|
|||
|
||||
char *password; /* Password used for MD5 authentication */
|
||||
struct rtable_config *igp_table; /* Table used for recursive next hop lookups */
|
||||
int check_link; /* Use iface link state for liveness detection */
|
||||
int bfd; /* Use BFD for liveness detection */
|
||||
};
|
||||
|
||||
|
@ -335,8 +336,9 @@ void bgp_log_error(struct bgp_proto *p, u8 class, char *msg, unsigned code, unsi
|
|||
#define BEM_INVALID_NEXT_HOP 2
|
||||
#define BEM_INVALID_MD5 3 /* MD5 authentication kernel request failed (possibly not supported) */
|
||||
#define BEM_NO_SOCKET 4
|
||||
#define BEM_BFD_DOWN 5
|
||||
#define BEM_GRACEFUL_RESTART 6
|
||||
#define BEM_LINK_DOWN 5
|
||||
#define BEM_BFD_DOWN 6
|
||||
#define BEM_GRACEFUL_RESTART 7
|
||||
|
||||
/* Automatic shutdown error codes */
|
||||
|
||||
|
|
|
@ -26,7 +26,8 @@ CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY,
|
|||
PREFER, OLDER, MISSING, LLADDR, DROP, IGNORE, ROUTE, REFRESH,
|
||||
INTERPRET, COMMUNITIES, BGP_ORIGINATOR_ID, BGP_CLUSTER_LIST, IGP,
|
||||
TABLE, GATEWAY, DIRECT, RECURSIVE, MED, TTL, SECURITY, DETERMINISTIC,
|
||||
SECONDARY, ALLOW, BFD, ADD, PATHS, RX, TX, GRACEFUL, RESTART, AWARE)
|
||||
SECONDARY, ALLOW, BFD, ADD, PATHS, RX, TX, GRACEFUL, RESTART, AWARE,
|
||||
CHECK, LINK)
|
||||
|
||||
CF_GRAMMAR
|
||||
|
||||
|
@ -97,7 +98,7 @@ bgp_proto:
|
|||
| bgp_proto DEFAULT BGP_LOCAL_PREF expr ';' { BGP_CFG->default_local_pref = $4; }
|
||||
| bgp_proto SOURCE ADDRESS ipa ';' { BGP_CFG->source_addr = $4; }
|
||||
| bgp_proto START DELAY TIME expr ';' { BGP_CFG->start_delay_time = $5; }
|
||||
| bgp_proto ERROR FORGET TIME expr ';' { BGP_CFG->error_amnesia_time = $5; }
|
||||
| bgp_proto ERROR FORGET TIME expr ';' { BGP_CFG->error_amnesia_time = $5; }
|
||||
| bgp_proto ERROR WAIT TIME expr ',' expr ';' { BGP_CFG->error_delay_time_min = $5; BGP_CFG->error_delay_time_max = $7; }
|
||||
| bgp_proto DISABLE AFTER ERROR bool ';' { BGP_CFG->disable_after_error = $5; }
|
||||
| bgp_proto ENABLE ROUTE REFRESH bool ';' { BGP_CFG->enable_refresh = $5; }
|
||||
|
@ -123,6 +124,7 @@ bgp_proto:
|
|||
| bgp_proto GRACEFUL RESTART TIME expr ';' { BGP_CFG->gr_time = $5; }
|
||||
| bgp_proto IGP TABLE rtable ';' { BGP_CFG->igp_table = $4; }
|
||||
| bgp_proto TTL SECURITY bool ';' { BGP_CFG->ttl_security = $4; }
|
||||
| bgp_proto CHECK LINK bool ';' { BGP_CFG->check_link = $4; }
|
||||
| bgp_proto BFD bool ';' { BGP_CFG->bfd = $3; cf_check_bfd($3); }
|
||||
;
|
||||
|
||||
|
|
Loading…
Reference in a new issue