struct ea_list *eattrs; /* Extended Attribute chain */
struct hostentry *hostentry; /* Hostentry for recursive next-hops */
ip_addr from; /* Advertising router */
- u32 igp_metric; /* IGP metric to next hop (for iBGP routes) */
u16 cached:1; /* Are attributes cached? */
u16 source:7; /* Route source (RTS_...) */
u16 scope:4; /* Route scope (SCOPE_... -- see ip.h) */
#define RTD_PROHIBIT 4 /* Administratively prohibited */
#define RTD_MAX 5
-#define IGP_METRIC_UNKNOWN 0x80000000 /* Default igp_metric used when no other
- protocol-specific metric is availabe */
-
-
extern const char * rta_dest_names[RTD_MAX];
static inline const char *rta_dest_name(uint n)
struct ea_class *class;
};
+#define IGP_METRIC_UNKNOWN 0x80000000 /* Default igp_metric used when no other
+ protocol-specific metric is availabe */
extern struct ea_class ea_gen_igp_metric;
void ea_register_init(struct ea_class *);
#define BMIX(f) mem_hash_mix_num(&h, a->f);
MIX(hostentry);
MIX(from);
- MIX(igp_metric);
BMIX(source);
BMIX(scope);
BMIX(dest);
return (x->source == y->source &&
x->scope == y->scope &&
x->dest == y->dest &&
- x->igp_metric == y->igp_metric &&
ipa_equal(x->from, y->from) &&
x->hostentry == y->hostentry &&
nexthop_same(&(x->nh), &(y->nh)) &&
{
a->hostentry = he;
a->dest = he->dest;
- a->igp_metric = he->igp_metric;
+
+ ea_set_attr_u32(&a->eattrs, &ea_gen_igp_metric, 0, he->igp_metric);
if (a->dest != RTD_UNICAST)
{
if (!he->src)
return a->dest != RTD_UNREACHABLE;
- return (a->dest != he->dest) || (a->igp_metric != he->igp_metric) ||
+ return (a->dest != he->dest) ||
+ (ea_get_int(a->eattrs, &ea_gen_igp_metric, IGP_METRIC_UNKNOWN) != he->igp_metric) ||
(!he->nexthop_linkable) || !nexthop_same(&(a->nh), &(he->src->nh));
}
return 0;
u64 aigp = get_u64(b + 3);
- u64 step = e->attrs->igp_metric;
+ u64 step = rt_get_igp_metric(e);
if (!rte_resolvable(e) || (step >= IGP_METRIC_UNKNOWN))
step = BGP_AIGP_MAX;
return 1;
/* 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;
+ n = new_bgp->cf->igp_metric ? rt_get_igp_metric(new) : 0;
+ o = old_bgp->cf->igp_metric ? rt_get_igp_metric(old) : 0;
if (n < o)
return 1;
if (n > o)
return 0;
/* RFC 4271 9.1.2.2. e) Compare IGP metrics */
- p = pri_bgp->cf->igp_metric ? pri->attrs->igp_metric : 0;
- s = sec_bgp->cf->igp_metric ? sec->attrs->igp_metric : 0;
+ p = pri_bgp->cf->igp_metric ? rt_get_igp_metric(pri) : 0;
+ s = sec_bgp->cf->igp_metric ? rt_get_igp_metric(sec) : 0;
if (p != s)
return 0;
{
buf += bsprintf(buf, "/%lu", metric);
}
- else if (e->attrs->igp_metric)
+ else if (metric = rt_get_igp_metric(e))
{
if (!rte_resolvable(e))
buf += bsprintf(buf, "/-");
- else if (e->attrs->igp_metric >= IGP_METRIC_UNKNOWN)
+ else if (metric >= IGP_METRIC_UNKNOWN)
buf += bsprintf(buf, "/?");
else
- buf += bsprintf(buf, "/%d", e->attrs->igp_metric);
+ buf += bsprintf(buf, "/%d", metric);
}
buf += bsprintf(buf, ") [");
a->dest = RTD_UNICAST;
a->nh.gw = nbr->addr;
a->nh.iface = nbr->iface;
- a->igp_metric = c->cf->cost;
+ ea_set_attr_u32(&a->eattrs, &ea_gen_igp_metric, 0, c->cf->cost);
}
else /* GW_RECURSIVE */
{