diff --git a/doc/bird.sgml b/doc/bird.sgml index 86f4c507..b35f4944 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -1121,7 +1121,7 @@ for each neighbor using the following configuration parameters: BIRD does not implement obsoleted RFC 1863, but uses ad-hoc implementation, which behaves like plain EBGP but reduces modifications to advertised route attributes to be transparent (for example does not prepend its AS number to - AS PATH attribute and keep MED attribute). Default: disabled. + AS PATH attribute and keeps MED attribute). Default: disabled. enable route refresh When BGP speaker changes its import filter, it has to re-examine all routes @@ -1205,6 +1205,15 @@ 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. + med metric Enable comparison of MED + attributes (during best route selection) even between routes + received from different ASes. This may be useful if all MED + attributes contain some consistent metric, perhaps enforced in + import filters of AS boundary routers. If this option is + disabled, MED attributes are compared only if routes are + received from the same AS (which is the standard behavior). + Default: off. + igp metric Enable comparison of internal distances to boundary routers during best route selection. Default: on. @@ -1233,21 +1242,21 @@ with ` bgppath Sequence of AS numbers describing the AS path - the packet will travel through when forwarded according to the particular route. In case of - internal BGP it doesn't contain the number of the local AS. + the packet will travel through when forwarded according to the particular route. + In case of internal BGP it doesn't contain the number of the local AS. int Local preference value used for selection among multiple BGP routes (see the selection rules above). It's used as an additional metric which is propagated through the whole local AS. int The Multiple Exit Discriminator of the route - is an optional attribute which is used on on external (inter-AS) links to + is an optional attribute which is used on external (inter-AS) links to convey to an adjacent AS the optimal entry point into the local AS. - The received attribute may be also propagated over internal BGP links - (and this is default behavior). The attribute value is zeroed when a route - is exported from a routing table to a BGP instance to ensure that the attribute - received from a neighboring AS is not propagated to other neighboring ASes. - A new value might be set in the export filter of a BGP instance. + The received attribute is also propagated over internal BGP links. + The attribute value is zeroed when a route is exported to an external BGP + instance to ensure that the attribute received from a neighboring AS is + not propagated to other neighboring ASes. A new value might be set in + the export filter of an external BGP instance. See RFC 4451 for further discussion of BGP MED attribute. @@ -1281,11 +1290,11 @@ with `quad This attribute is created by the + quad This attribute is created by the route reflector when reflecting the route and contains the router ID of the originator of the route in the local AS. - clist This attribute contains a list + clist This attribute contains a list of cluster IDs of route reflectors. Each route reflector prepends its cluster ID when reflecting the route. diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c index e1a3671a..95eee9aa 100644 --- a/proto/bgp/attrs.c +++ b/proto/bgp/attrs.c @@ -1118,7 +1118,17 @@ 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)) + /* This is noncompliant. Proper RFC 4271 path selection cannot be + * interpreted as finding the best path in some ordering. + * Therefore, it cannot be implemented in BIRD without some ugly + * hacks. This is just an approximation, which in specific + * situations may lead to persistent routing loops, because it is + * nondeterministic - it depends on the order in which routes + * appeared. But it is also the same behavior as used by default in + * Cisco routers, so it is probably not a big issue. + */ + if (new_bgp->cf->med_metric || old_bgp->cf->med_metric || + (bgp_get_neighbor(new) == bgp_get_neighbor(old))) { x = ea_find(new->attrs->eattrs, EA_CODE(EAP_BGP, BA_MULTI_EXIT_DISC)); y = ea_find(old->attrs->eattrs, EA_CODE(EAP_BGP, BA_MULTI_EXIT_DISC)); diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h index b06f20a0..097faa6a 100644 --- a/proto/bgp/bgp.h +++ b/proto/bgp/bgp.h @@ -25,6 +25,7 @@ struct bgp_config { int missing_lladdr; /* What we will do when we don' know link-local addr, see MLL_* */ int gw_mode; /* How we compute route gateway from next_hop attr, see GW_* */ int compare_path_lengths; /* Use path lengths when selecting best route */ + int med_metric; /* Compare MULTI_EXIT_DISC even between routes from differen ASes */ int igp_metric; /* Use IGP metrics when selecting best route */ int prefer_older; /* Prefer older routes according to RFC 5004 */ u32 default_local_pref; /* Default value for LOCAL_PREF attribute */ diff --git a/proto/bgp/config.Y b/proto/bgp/config.Y index e932a7f6..93f832aa 100644 --- a/proto/bgp/config.Y +++ b/proto/bgp/config.Y @@ -25,7 +25,7 @@ CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY, ADVERTISE, IPV4, CAPABILITIES, LIMIT, PASSIVE, PREFER, OLDER, MISSING, LLADDR, DROP, IGNORE, ROUTE, REFRESH, INTERPRET, COMMUNITIES, BGP_ORIGINATOR_ID, BGP_CLUSTER_LIST, IGP, TABLE, - GATEWAY, DIRECT, RECURSIVE) + GATEWAY, DIRECT, RECURSIVE, MED) CF_GRAMMAR @@ -79,6 +79,7 @@ bgp_proto: | bgp_proto GATEWAY DIRECT ';' { BGP_CFG->gw_mode = GW_DIRECT; } | bgp_proto GATEWAY RECURSIVE ';' { BGP_CFG->gw_mode = GW_RECURSIVE; } | bgp_proto PATH METRIC bool ';' { BGP_CFG->compare_path_lengths = $4; } + | bgp_proto MED METRIC bool ';' { BGP_CFG->med_metric = $4; } | bgp_proto IGP METRIC bool ';' { BGP_CFG->igp_metric = $4; } | bgp_proto PREFER OLDER bool ';' { BGP_CFG->prefer_older = $4; } | bgp_proto DEFAULT BGP_MED expr ';' { BGP_CFG->default_med = $4; }