From 73272f04af40484b72451f541a986da996b0da58 Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Fri, 22 Apr 2011 16:13:27 +0200 Subject: Adds BGP option related to MED handling. Adds option 'med metric' allows to compare MEDs between routes received from different neighbors. --- proto/bgp/attrs.c | 12 +++++++++++- proto/bgp/bgp.h | 1 + proto/bgp/config.Y | 3 ++- 3 files changed, 14 insertions(+), 2 deletions(-) (limited to 'proto/bgp') diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c index e1a3671..95eee9a 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 b06f20a..097faa6 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 e932a7f..93f832a 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; } -- cgit v1.2.3