From d1e146f2f8da303af7bbe0cec363cc15c58c37fd Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Sat, 31 Jul 2010 01:04:32 +0200 Subject: Implements IGP metric comparison for BGP routes. --- proto/bgp/attrs.c | 22 +++++++++++++++++++--- proto/bgp/bgp.h | 1 + proto/bgp/config.Y | 2 ++ proto/bgp/packets.c | 1 + 4 files changed, 23 insertions(+), 3 deletions(-) (limited to 'proto') diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c index 3e7c94a6..ef5d024e 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 6bb1d6e5..b06f20a0 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 75b93391..e932a7f6 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 632c564e..29d23b99 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); -- cgit v1.2.3