From 3228c72cc030f409914134440a7e55bbcfc9ff6a Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Tue, 17 Nov 2009 11:41:29 +0100 Subject: [PATCH] Implements RFC 5004 - prefer older external routes. --- doc/bird.sgml | 5 +++++ proto/bgp/attrs.c | 10 ++++++++-- proto/bgp/bgp.h | 1 + proto/bgp/config.Y | 3 ++- 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/doc/bird.sgml b/doc/bird.sgml index 0c2b8fbe..40793ed3 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -981,6 +981,11 @@ for each neighbor using the following configuration parameters: path metric Enable comparison of path lengths when deciding which BGP route is the best one. Default: on. + prefer older Standard route selection algorithm + breaks ties by comparing router IDs. This changes the behavior + to prefer older routes (when both are external and from different + peer). For details, see RFC 5004. Default: off. + default bgp_med Value of the Multiple Exit Discriminator to be used during route selection when the MED attribute is missing. Default: 0. diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c index d839ed09..9c7bc30a 100644 --- a/proto/bgp/attrs.c +++ b/proto/bgp/attrs.c @@ -1044,7 +1044,6 @@ bgp_rte_better(rte *new, rte *old) return 0; /* RFC 4271 9.1.2.2. c) Compare MED's */ - if (bgp_get_neighbor(new) == bgp_get_neighbor(old)) { x = ea_find(new->attrs->eattrs, EA_CODE(EAP_BGP, BA_MULTI_EXIT_DISC)); @@ -1082,12 +1081,19 @@ bgp_rte_better(rte *new, rte *old) y = ea_find(old->attrs->eattrs, EA_CODE(EAP_BGP, BA_ORIGINATOR_ID)); n = x ? x->u.data : new_bgp->remote_id; o = y ? y->u.data : old_bgp->remote_id; + + /* RFC 5004 - prefer older routes */ + /* (if both are external and from different peer) */ + if ((new_bgp->cf->prefer_older || old_bgp->cf->prefer_older) && + !new_bgp->is_internal && n != o) + return 0; + + /* rest of RFC 4271 9.1.2.2. f) */ if (n < o) return 1; if (n > o) return 0; - /* RFC 4271 9.1.2.2. g) Compare peer IP adresses */ return (ipa_compare(new_bgp->cf->remote_ip, old_bgp->cf->remote_ip) < 0); } diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h index 0a82be2b..c487aafb 100644 --- a/proto/bgp/bgp.h +++ b/proto/bgp/bgp.h @@ -24,6 +24,7 @@ struct bgp_config { ip_addr source_addr; /* Source address to use */ int next_hop_self; /* Always set next hop to local IP address */ int compare_path_lengths; /* Use path lengths when selecting best route */ + int prefer_older; /* Prefer older routes according to RFC 5004 */ u32 default_local_pref; /* Default value for LOCAL_PREF attribute */ u32 default_med; /* Default value for MULTI_EXIT_DISC attribute */ int capabilities; /* Enable capability handshake [RFC3392] */ diff --git a/proto/bgp/config.Y b/proto/bgp/config.Y index 7360820f..94011750 100644 --- a/proto/bgp/config.Y +++ b/proto/bgp/config.Y @@ -22,7 +22,7 @@ CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY, KEEPALIVE, BGP_PATH, BGP_LOCAL_PREF, BGP_MED, BGP_ORIGIN, BGP_NEXT_HOP, BGP_ATOMIC_AGGR, BGP_AGGREGATOR, BGP_COMMUNITY, SOURCE, ADDRESS, PASSWORD, RR, RS, CLIENT, CLUSTER, ID, AS4, ADVERTISE, IPV4, - CAPABILITIES, LIMIT, PASSIVE) + CAPABILITIES, LIMIT, PASSIVE, PREFER, OLDER) CF_GRAMMAR @@ -65,6 +65,7 @@ bgp_proto: | bgp_proto MULTIHOP expr VIA ipa ';' { BGP_CFG->multihop = $3; BGP_CFG->multihop_via = $5; } | bgp_proto NEXT HOP SELF ';' { BGP_CFG->next_hop_self = 1; } | bgp_proto PATH METRIC bool ';' { BGP_CFG->compare_path_lengths = $4; } + | bgp_proto PREFER OLDER bool ';' { BGP_CFG->prefer_older = $4; } | bgp_proto DEFAULT BGP_MED expr ';' { BGP_CFG->default_med = $4; } | bgp_proto DEFAULT BGP_LOCAL_PREF expr ';' { BGP_CFG->default_local_pref = $4; } | bgp_proto SOURCE ADDRESS ipa ';' { BGP_CFG->source_addr = $4; }