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:
parent
4e379bde60
commit
1950a479c0
4 changed files with 25 additions and 5 deletions
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
Loading…
Reference in a new issue