[RFC,PATCH 1/2] BGP: Implement iebgp_peer mode.
Lennert Buytenhek
buytenh at wantstofly.org
Sat Aug 12 21:22:06 CEST 2017
Implement an 'internal eBGP' peer mode, where the remote peer uses a
different AS number than we do, as if it were an eBGP peer, but we
treat the peer as if were an AS-internal peer. This enables
implementing a network setup according to the model documented in
RFC7938. This makes two changes to the BGP route propagation logic:
* When we are propagating a route to or from an internal eBGP peer,
we will avoid resetting the MED attribute.
* When comparing BGP-learned routes, we will consider routes learned
from an 'internal eBGP' peer as iBGP routes as far as the RFC 4271
9.1.2.2. d) check (Prefer external peers) is concerned.
---
proto/bgp/attrs.c | 22 ++++++++++++++++------
proto/bgp/bgp.h | 1 +
proto/bgp/config.Y | 4 +++-
3 files changed, 20 insertions(+), 7 deletions(-)
diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c
index b9e2490d..478c805c 100644
--- a/proto/bgp/attrs.c
+++ b/proto/bgp/attrs.c
@@ -1100,15 +1100,21 @@ bgp_update_attrs(struct bgp_proto *p, rte *e, ea_list **attrs, struct linpool *p
if (!p->is_internal && !p->rs_client)
{
+ struct bgp_proto *new_bgp = (e->attrs->src->proto->proto == &proto_bgp) ?
+ (struct bgp_proto *) e->attrs->src->proto : NULL;
+
bgp_path_prepend(e, attrs, pool, p->local_as);
/* The MULTI_EXIT_DISC attribute received from a neighboring AS MUST NOT be
* propagated to other neighboring ASes.
* Perhaps it would be better to undefine it.
*/
- a = ea_find(e->attrs->eattrs, EA_CODE(EAP_BGP, BA_MULTI_EXIT_DISC));
- if (a)
- bgp_attach_attr(attrs, pool, BA_MULTI_EXIT_DISC, 0);
+ if (!p->cf->iebgp_peer && (new_bgp == NULL || !new_bgp->cf->iebgp_peer))
+ {
+ a = ea_find(e->attrs->eattrs, EA_CODE(EAP_BGP, BA_MULTI_EXIT_DISC));
+ if (a)
+ bgp_attach_attr(attrs, pool, BA_MULTI_EXIT_DISC, 0);
+ }
}
/* iBGP -> keep next_hop, eBGP multi-hop -> use source_addr,
@@ -1317,9 +1323,11 @@ bgp_rte_better(rte *new, rte *old)
}
/* RFC 4271 9.1.2.2. d) Prefer external peers */
- if (new_bgp->is_internal > old_bgp->is_internal)
+ n = !!(new_bgp->is_internal || new_bgp->cf->iebgp_peer);
+ o = !!(old_bgp->is_internal || old_bgp->cf->iebgp_peer);
+ if (n > o)
return 0;
- if (new_bgp->is_internal < old_bgp->is_internal)
+ if (n < o)
return 1;
/* RFC 4271 9.1.2.2. e) Compare IGP metrics */
@@ -1424,7 +1432,9 @@ bgp_rte_mergable(rte *pri, rte *sec)
}
/* RFC 4271 9.1.2.2. d) Prefer external peers */
- if (pri_bgp->is_internal != sec_bgp->is_internal)
+ p = !!(pri_bgp->is_internal || pri_bgp->cf->iebgp_peer);
+ s = !!(sec_bgp->is_internal || sec_bgp->cf->iebgp_peer);
+ if (p != s)
return 0;
/* RFC 4271 9.1.2.2. e) Compare IGP metrics */
diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h
index e47a0eb1..8652fae8 100644
--- a/proto/bgp/bgp.h
+++ b/proto/bgp/bgp.h
@@ -51,6 +51,7 @@ struct bgp_config {
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 iebgp_peer; /* Peer has different AS but should be treated as internal peer */
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 55c602f1..f01a6fb6 100644
--- a/proto/bgp/config.Y
+++ b/proto/bgp/config.Y
@@ -27,7 +27,8 @@ CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY,
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,
- CHECK, LINK, PORT, EXTENDED, MESSAGES, SETKEY, BGP_LARGE_COMMUNITY)
+ CHECK, LINK, PORT, EXTENDED, MESSAGES, SETKEY, BGP_LARGE_COMMUNITY,
+ IEBGP_PEER)
CF_GRAMMAR
@@ -129,6 +130,7 @@ bgp_proto:
| 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 IEBGP_PEER bool ';' { BGP_CFG->iebgp_peer = $3; }
| bgp_proto GRACEFUL RESTART bool ';' { BGP_CFG->gr_mode = $4; }
| bgp_proto GRACEFUL RESTART AWARE ';' { BGP_CFG->gr_mode = BGP_GR_AWARE; }
| bgp_proto GRACEFUL RESTART TIME expr ';' { BGP_CFG->gr_time = $5; }
--
2.13.4
More information about the Bird-users
mailing list