summaryrefslogtreecommitdiff
path: root/proto
diff options
context:
space:
mode:
authorOndrej Zajicek (work) <santiago@crfreenet.org>2017-02-23 16:32:07 +0100
committerOndrej Zajicek (work) <santiago@crfreenet.org>2017-02-23 16:32:07 +0100
commit1950a479c020d1972b6007d8ea0f66e3d4f8564a (patch)
tree6f023363fb7536eb912e4b373039e8c283626a8b /proto
parent4e379bde60172823452cf96e9c0b6b1737c490f0 (diff)
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.
Diffstat (limited to 'proto')
-rw-r--r--proto/bgp/attrs.c20
-rw-r--r--proto/bgp/bgp.h1
-rw-r--r--proto/bgp/config.Y1
3 files changed, 17 insertions, 5 deletions
diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c
index 2b0a92dc..b9e2490d 100644
--- a/proto/bgp/attrs.c
+++ b/proto/bgp/attrs.c
@@ -306,7 +306,7 @@ static struct attr_desc bgp_attr_table[] = {
bgp_check_next_hop, bgp_format_next_hop },
{ "med", 4, BAF_OPTIONAL, EAF_TYPE_INT, 1, /* BA_MULTI_EXIT_DISC */
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 },
{ "atomic_aggr", 0, BAF_TRANSITIVE, EAF_TYPE_OPAQUE, 1, /* BA_ATOMIC_AGGR */
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);
if (ATTR_KNOWN(code))
{
- if (!bgp_attr_table[code].allow_in_ebgp && !p->is_internal)
- continue;
+ if (!p->is_internal)
+ {
+ if (!bgp_attr_table[code].allow_in_ebgp)
+ 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 */
a->flags = (a->flags & BAF_PARTIAL) | bgp_attr_table[code].expected_flags;
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; }
if ((desc->expected_flags ^ flags) & (BAF_OPTIONAL | BAF_TRANSITIVE))
{ errcode = 4; goto err; }
- if (!desc->allow_in_ebgp && !bgp->is_internal)
- continue;
+ if (!bgp->is_internal)
+ {
+ if (!desc->allow_in_ebgp)
+ continue;
+ if ((code == BA_LOCAL_PREF) && !bgp->cf->allow_local_pref)
+ continue;
+ }
if (desc->validate)
{
errcode = desc->validate(bgp, z, l);
diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h
index bf933554..e47a0eb1 100644
--- a/proto/bgp/bgp.h
+++ b/proto/bgp/bgp.h
@@ -50,6 +50,7 @@ struct bgp_config {
int secondary; /* Accept also non-best routes (i.e. RA_ACCEPTED) */
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_pref; /* Allow LOCAL_PREF in EBGP sessions */
int gr_mode; /* Graceful restart mode (BGP_GR_*) */
int setkey; /* Set MD5 password to system SA/SP database */
unsigned gr_time; /* Graceful restart timeout */
diff --git a/proto/bgp/config.Y b/proto/bgp/config.Y
index 32ae88a3..55c602f1 100644
--- a/proto/bgp/config.Y
+++ b/proto/bgp/config.Y
@@ -126,6 +126,7 @@ bgp_proto:
| 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 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 expr ';' { BGP_CFG->allow_local_as = $5; }
| bgp_proto GRACEFUL RESTART bool ';' { BGP_CFG->gr_mode = $4; }