]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Implements RFC 5004 - prefer older external routes.
authorOndrej Zajicek <santiago@crfreenet.org>
Tue, 17 Nov 2009 10:41:29 +0000 (11:41 +0100)
committerOndrej Zajicek <santiago@crfreenet.org>
Tue, 17 Nov 2009 10:41:29 +0000 (11:41 +0100)
doc/bird.sgml
proto/bgp/attrs.c
proto/bgp/bgp.h
proto/bgp/config.Y

index 0c2b8fbe87c068bd2ab88df2cbb8116f783509b5..40793ed37fbda7731235d325d83e8813818e3e45 100644 (file)
@@ -981,6 +981,11 @@ for each neighbor using the following configuration parameters:
        <tag>path metric <m/switch/</tag> Enable comparison of path lengths
        when deciding which BGP route is the best one. Default: on.
 
+       <tag>prefer older <m/switch/</tag> 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.
+
        <tag>default bgp_med <m/number/</tag> Value of the Multiple Exit
        Discriminator to be used during route selection when the MED attribute
        is missing. Default: 0.
index d839ed09af6d46a22afa73f834b48a147414d6e9..9c7bc30a214222d08c7521ef50bf7c55210b4878 100644 (file)
@@ -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);
 }
index 0a82be2be7c9c5c080b53ee8f511b7bfd71e3b0a..c487aafb582f64476161b0b21cad9339da09a2b4 100644 (file)
@@ -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] */
index 7360820f06bd94f555d009bce0867eaa12511af5..94011750d037f03d40ab8ffc4cfe245259cf578c 100644 (file)
@@ -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; }