summaryrefslogtreecommitdiffstats
path: root/proto
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2010-07-31 01:04:32 +0200
committerOndrej Zajicek <santiago@crfreenet.org>2010-07-31 01:04:32 +0200
commitd1e146f2f8da303af7bbe0cec363cc15c58c37fd (patch)
tree7179724c7752d0c3ae5801736f8071b71243c60e /proto
parentac3ac49a71d4b290cfb28aecafc8ac4a69df7a64 (diff)
downloadbird-d1e146f2f8da303af7bbe0cec363cc15c58c37fd.tar
bird-d1e146f2f8da303af7bbe0cec363cc15c58c37fd.zip
Implements IGP metric comparison for BGP routes.
Diffstat (limited to 'proto')
-rw-r--r--proto/bgp/attrs.c22
-rw-r--r--proto/bgp/bgp.h1
-rw-r--r--proto/bgp/config.Y2
-rw-r--r--proto/bgp/packets.c1
4 files changed, 23 insertions, 3 deletions
diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c
index 3e7c94a..ef5d024 100644
--- a/proto/bgp/attrs.c
+++ b/proto/bgp/attrs.c
@@ -1084,8 +1084,13 @@ bgp_rte_better(rte *new, rte *old)
if (new_bgp->is_internal < old_bgp->is_internal)
return 1;
- /* Skipping RFC 4271 9.1.2.2. e) */
- /* We don't have interior distances */
+ /* RFC 4271 9.1.2.2. e) Compare IGP metrics */
+ n = new_bgp->cf->igp_metric ? new->attrs->igp_metric : 0;
+ o = old_bgp->cf->igp_metric ? old->attrs->igp_metric : 0;
+ if (n < o)
+ return 1;
+ if (n > o)
+ return 0;
/* RFC 4271 9.1.2.2. f) Compare BGP identifiers */
/* RFC 4456 9. a) Use ORIGINATOR_ID instead of local neighor ID */
@@ -1494,7 +1499,18 @@ bgp_get_route_info(rte *e, byte *buf, ea_list *attrs)
eattr *o = ea_find(attrs, EA_CODE(EAP_BGP, BA_ORIGIN));
u32 origas;
- buf += bsprintf(buf, " (%d) [", e->pref);
+ buf += bsprintf(buf, " (%d", e->pref);
+ if (e->attrs->hostentry)
+ {
+ if (!e->attrs->iface)
+ buf += bsprintf(buf, "/-");
+ else if (e->attrs->igp_metric >= IGP_METRIC_UNKNOWN)
+ buf += bsprintf(buf, "/?");
+ else
+ buf += bsprintf(buf, "/%d", e->attrs->igp_metric);
+ }
+ buf += bsprintf(buf, ") [");
+
if (p && as_path_get_last(p->u.ptr, &origas))
buf += bsprintf(buf, "AS%u", origas);
if (o)
diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h
index 6bb1d6e..b06f20a 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 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 */
u32 default_med; /* Default value for MULTI_EXIT_DISC attribute */
diff --git a/proto/bgp/config.Y b/proto/bgp/config.Y
index 75b9339..e932a7f 100644
--- a/proto/bgp/config.Y
+++ b/proto/bgp/config.Y
@@ -38,6 +38,7 @@ bgp_proto_start: proto_start BGP {
BGP_CFG->connect_retry_time = 120;
BGP_CFG->initial_hold_time = 240;
BGP_CFG->compare_path_lengths = 1;
+ BGP_CFG->igp_metric = 1;
BGP_CFG->start_delay_time = 5;
BGP_CFG->error_amnesia_time = 300;
BGP_CFG->error_delay_time_min = 60;
@@ -78,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 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; }
| bgp_proto DEFAULT BGP_LOCAL_PREF expr ';' { BGP_CFG->default_local_pref = $4; }
diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c
index 632c564..29d23b9 100644
--- a/proto/bgp/packets.c
+++ b/proto/bgp/packets.c
@@ -823,6 +823,7 @@ bgp_set_next_hop(struct bgp_proto *p, rta *a)
a->gw = ng->addr;
a->iface = ng->iface;
a->hostentry = NULL;
+ a->igp_metric = 0;
}
else /* GW_RECURSIVE */
rta_set_recursive_next_hop(p->p.table, a, p->igp_table, nexthop, nexthop + second);