struct rte * (*rte_modify)(struct rte *, struct linpool *);
void (*rte_insert)(struct network *, struct rte *);
void (*rte_remove)(struct network *, struct rte *);
+ u32 (*rte_igp_metric)(struct rte *);
/* Hic sunt protocol-specific data */
};
#include "lib/string.h"
#include "lib/alloca.h"
-#ifdef CONFIG_BGP
-#include "proto/bgp/bgp.h"
-#endif
-
pool *rt_table_pool;
static slab *rte_slab;
if (ea)
return ea->u.data;
- rta *a = rt->attrs;
-
-#ifdef CONFIG_OSPF
- if ((a->source == RTS_OSPF) ||
- (a->source == RTS_OSPF_IA) ||
- (a->source == RTS_OSPF_EXT1))
- return rt->u.ospf.metric1;
-#endif
-
-#ifdef CONFIG_RIP
- if (a->source == RTS_RIP)
- return rt->u.rip.metric;
-#endif
-
-#ifdef CONFIG_BGP
- if (a->source == RTS_BGP)
- {
- u64 metric = bgp_total_aigp_metric(rt);
- return (u32) MIN(metric, (u64) IGP_METRIC_UNKNOWN);
- }
-#endif
-
-#ifdef CONFIG_BABEL
- if (a->source == RTS_BABEL)
- return rt->u.babel.metric;
-#endif
-
- if (a->source == RTS_DEVICE)
+ if (rt->attrs->source == RTS_DEVICE)
return 0;
+ if (rt->src->proto->rte_igp_metric)
+ return rt->src->proto->rte_igp_metric(rt);
+
return IGP_METRIC_UNKNOWN;
}
(new->u.babel.router_id == old->u.babel.router_id));
}
+static u32
+babel_rte_igp_metric(struct rte *rt)
+{
+ return rt->u.babel.metric;
+}
+
static void
babel_postconfig(struct proto_config *CF)
P->store_tmp_attrs = babel_store_tmp_attrs;
P->rte_better = babel_rte_better;
P->rte_same = babel_rte_same;
+ P->rte_igp_metric = babel_rte_igp_metric;
return P;
}
return *metric < IGP_METRIC_UNKNOWN;
}
+u32
+bgp_rte_igp_metric(struct rte *rt)
+{
+ u64 metric = bgp_total_aigp_metric(rt);
+ return (u32) MIN(metric, (u64) IGP_METRIC_UNKNOWN);
+}
+
/*
* Attribute hooks
P->rte_mergable = bgp_rte_mergable;
P->rte_recalculate = cf->deterministic_med ? bgp_rte_recalculate : NULL;
P->rte_modify = bgp_rte_modify_stale;
+ P->rte_igp_metric = bgp_rte_igp_metric;
p->cf = cf;
p->is_internal = (cf->local_as == cf->remote_as);
int bgp_rte_mergable(rte *pri, rte *sec);
int bgp_rte_recalculate(rtable *table, net *net, rte *new, rte *old, rte *old_best);
struct rte *bgp_rte_modify_stale(struct rte *r, struct linpool *pool);
+u32 bgp_rte_igp_metric(struct rte *);
void bgp_rt_notify(struct proto *P, struct channel *C, net *n, rte *new, rte *old);
int bgp_preexport(struct proto *, struct rte *);
int bgp_get_attr(const struct eattr *e, byte *buf, int buflen);
static void ospf_reload_routes(struct channel *C);
static int ospf_rte_better(struct rte *new, struct rte *old);
static int ospf_rte_same(struct rte *new, struct rte *old);
+static u32 ospf_rte_igp_metric(struct rte *rt);
static void ospf_disp(timer *timer);
P->store_tmp_attrs = ospf_store_tmp_attrs;
P->rte_better = ospf_rte_better;
P->rte_same = ospf_rte_same;
+ P->rte_igp_metric = ospf_rte_igp_metric;
return P;
}
new->u.ospf.router_id == old->u.ospf.router_id;
}
+static u32
+ospf_rte_igp_metric(struct rte *rt)
+{
+ return rt->u.ospf.metric1;
+}
void
ospf_schedule_rtcalc(struct ospf_proto *p)
(new->u.rip.from == old->u.rip.from));
}
+static u32
+rip_rte_igp_metric(struct rte *rt)
+{
+ return rt->u.rip.metric;
+}
static void
rip_postconfig(struct proto_config *CF)
P->store_tmp_attrs = rip_store_tmp_attrs;
P->rte_better = rip_rte_better;
P->rte_same = rip_rte_same;
+ P->rte_igp_metric = rip_rte_igp_metric;
return P;
}