summaryrefslogtreecommitdiff
path: root/proto/bgp/attrs.c
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2011-04-22 16:13:27 +0200
committerOndrej Zajicek <santiago@crfreenet.org>2011-04-22 16:13:27 +0200
commit73272f04af40484b72451f541a986da996b0da58 (patch)
treedf2b6b6ee2696f034dcdb5404cde442730d60cc1 /proto/bgp/attrs.c
parent71ca77169d5d3e67459e46841b8bdb95accd8c2a (diff)
Adds BGP option related to MED handling.
Adds option 'med metric' allows to compare MEDs between routes received from different neighbors.
Diffstat (limited to 'proto/bgp/attrs.c')
-rw-r--r--proto/bgp/attrs.c12
1 files changed, 11 insertions, 1 deletions
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));