BGP: Allow exchanging LOCAL_PREF with eBGP peers

Adds option 'allow bgp_local_pref' to override the usual restriction of
LOCAL_PREF on eBGP sessions.

Thanks to Lennert Buytenhek for the patch.
This commit is contained in:
Ondrej Zajicek (work) 2017-02-23 16:32:07 +01:00
parent 4e379bde60
commit 1950a479c0
4 changed files with 25 additions and 5 deletions

View file

@ -2043,6 +2043,14 @@ using the following configuration parameters:
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-allow-local-pref">allow bgp_local_pref <m/switch/</tag>
A standard BGP implementation do not send the Local Preference attribute
to eBGP neighbors and ignore this attribute if received from eBGP
neighbors, as per <rfc id="4271">. When this option is enabled on an
eBGP session, this attribute will be sent to and accepted from the peer,
which is useful for example if you have a setup like in <rfc id="7938">.
The option does not affect iBGP sessions. Default: off.
<tag><label id="bgp-allow-local-as">allow local as [<m/number/]</tag> <tag><label id="bgp-allow-local-as">allow local as [<m/number/]</tag>
BGP prevents routing loops by rejecting received routes with the local 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 AS number in the AS path. This option allows to loose or disable the

View file

@ -306,7 +306,7 @@ static struct attr_desc bgp_attr_table[] = {
bgp_check_next_hop, bgp_format_next_hop }, bgp_check_next_hop, bgp_format_next_hop },
{ "med", 4, BAF_OPTIONAL, EAF_TYPE_INT, 1, /* BA_MULTI_EXIT_DISC */ { "med", 4, BAF_OPTIONAL, EAF_TYPE_INT, 1, /* BA_MULTI_EXIT_DISC */
NULL, NULL }, NULL, NULL },
{ "local_pref", 4, BAF_TRANSITIVE, EAF_TYPE_INT, 0, /* BA_LOCAL_PREF */ { "local_pref", 4, BAF_TRANSITIVE, EAF_TYPE_INT, 1, /* BA_LOCAL_PREF */
NULL, NULL }, NULL, NULL },
{ "atomic_aggr", 0, BAF_TRANSITIVE, EAF_TYPE_OPAQUE, 1, /* BA_ATOMIC_AGGR */ { "atomic_aggr", 0, BAF_TRANSITIVE, EAF_TYPE_OPAQUE, 1, /* BA_ATOMIC_AGGR */
NULL, NULL }, NULL, NULL },
@ -821,8 +821,13 @@ bgp_get_bucket(struct bgp_proto *p, net *n, ea_list *attrs, int originate)
code = EA_ID(a->id); code = EA_ID(a->id);
if (ATTR_KNOWN(code)) if (ATTR_KNOWN(code))
{ {
if (!bgp_attr_table[code].allow_in_ebgp && !p->is_internal) if (!p->is_internal)
{
if (!bgp_attr_table[code].allow_in_ebgp)
continue; continue;
if ((code == BA_LOCAL_PREF) && !p->cf->allow_local_pref)
continue;
}
/* The flags might have been zero if the attr was added by filters */ /* The flags might have been zero if the attr was added by filters */
a->flags = (a->flags & BAF_PARTIAL) | bgp_attr_table[code].expected_flags; a->flags = (a->flags & BAF_PARTIAL) | bgp_attr_table[code].expected_flags;
if (code < 32) if (code < 32)
@ -1776,8 +1781,13 @@ bgp_decode_attrs(struct bgp_conn *conn, byte *attr, uint len, struct linpool *po
{ errcode = 5; goto err; } { errcode = 5; goto err; }
if ((desc->expected_flags ^ flags) & (BAF_OPTIONAL | BAF_TRANSITIVE)) if ((desc->expected_flags ^ flags) & (BAF_OPTIONAL | BAF_TRANSITIVE))
{ errcode = 4; goto err; } { errcode = 4; goto err; }
if (!desc->allow_in_ebgp && !bgp->is_internal) if (!bgp->is_internal)
{
if (!desc->allow_in_ebgp)
continue; continue;
if ((code == BA_LOCAL_PREF) && !bgp->cf->allow_local_pref)
continue;
}
if (desc->validate) if (desc->validate)
{ {
errcode = desc->validate(bgp, z, l); errcode = desc->validate(bgp, z, l);

View file

@ -50,6 +50,7 @@ struct bgp_config {
int secondary; /* Accept also non-best routes (i.e. RA_ACCEPTED) */ int secondary; /* Accept also non-best routes (i.e. RA_ACCEPTED) */
int add_path; /* Use ADD-PATH extension [RFC7911] */ int add_path; /* Use ADD-PATH extension [RFC7911] */
int allow_local_as; /* Allow that number of local ASNs in incoming AS_PATHs */ int allow_local_as; /* Allow that number of local ASNs in incoming AS_PATHs */
int allow_local_pref; /* Allow LOCAL_PREF in EBGP sessions */
int gr_mode; /* Graceful restart mode (BGP_GR_*) */ int gr_mode; /* Graceful restart mode (BGP_GR_*) */
int setkey; /* Set MD5 password to system SA/SP database */ int setkey; /* Set MD5 password to system SA/SP database */
unsigned gr_time; /* Graceful restart timeout */ unsigned gr_time; /* Graceful restart timeout */

View file

@ -126,6 +126,7 @@ bgp_proto:
| bgp_proto ADD PATHS RX ';' { BGP_CFG->add_path = ADD_PATH_RX; } | bgp_proto ADD PATHS RX ';' { BGP_CFG->add_path = ADD_PATH_RX; }
| bgp_proto ADD PATHS TX ';' { BGP_CFG->add_path = ADD_PATH_TX; } | bgp_proto ADD PATHS TX ';' { BGP_CFG->add_path = ADD_PATH_TX; }
| bgp_proto ADD PATHS bool ';' { BGP_CFG->add_path = $4 ? ADD_PATH_FULL : 0; } | bgp_proto ADD PATHS bool ';' { BGP_CFG->add_path = $4 ? ADD_PATH_FULL : 0; }
| bgp_proto ALLOW BGP_LOCAL_PREF bool ';' { BGP_CFG->allow_local_pref = $4; }
| bgp_proto ALLOW LOCAL AS ';' { BGP_CFG->allow_local_as = -1; } | bgp_proto ALLOW LOCAL AS ';' { BGP_CFG->allow_local_as = -1; }
| bgp_proto ALLOW LOCAL AS expr ';' { BGP_CFG->allow_local_as = $5; } | bgp_proto ALLOW LOCAL AS expr ';' { BGP_CFG->allow_local_as = $5; }
| bgp_proto GRACEFUL RESTART bool ';' { BGP_CFG->gr_mode = $4; } | bgp_proto GRACEFUL RESTART bool ';' { BGP_CFG->gr_mode = $4; }