From d471d5fc7ce587ed836ca7fa10a79331bc181d45 Mon Sep 17 00:00:00 2001 From: Maria Matejka Date: Sat, 20 Mar 2021 23:18:34 +0100 Subject: [PATCH] IGP metric getter refactoring to protocol callback Direct protocol hooks for IGP metric inside nest/rt-table.c make the protocol API unnecessarily complex. Instead, we use a proper callback. --- nest/protocol.h | 1 + nest/rt-table.c | 36 ++++-------------------------------- proto/babel/babel.c | 7 +++++++ proto/bgp/attrs.c | 7 +++++++ proto/bgp/bgp.c | 1 + proto/bgp/bgp.h | 1 + proto/ospf/ospf.c | 7 +++++++ proto/rip/rip.c | 6 ++++++ 8 files changed, 34 insertions(+), 32 deletions(-) diff --git a/nest/protocol.h b/nest/protocol.h index 6ee97b7c..62fd2b66 100644 --- a/nest/protocol.h +++ b/nest/protocol.h @@ -241,6 +241,7 @@ struct proto { 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 */ }; diff --git a/nest/rt-table.c b/nest/rt-table.c index a869bb18..844c7a68 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -45,10 +45,6 @@ #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; @@ -3022,36 +3018,12 @@ rt_get_igp_metric(rte *rt) 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; } diff --git a/proto/babel/babel.c b/proto/babel/babel.c index 1d23aef7..d17f318b 100644 --- a/proto/babel/babel.c +++ b/proto/babel/babel.c @@ -2332,6 +2332,12 @@ babel_rte_same(struct rte *new, struct rte *old) (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) @@ -2367,6 +2373,7 @@ babel_init(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; } diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c index 10706088..18d2985c 100644 --- a/proto/bgp/attrs.c +++ b/proto/bgp/attrs.c @@ -371,6 +371,13 @@ bgp_init_aigp_metric(rte *e, u64 *metric, const struct adata **ad) 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 diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c index e4d754b1..5c78bfa1 100644 --- a/proto/bgp/bgp.c +++ b/proto/bgp/bgp.c @@ -1694,6 +1694,7 @@ bgp_init(struct proto_config *CF) 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); diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h index 20944fe6..c440c7af 100644 --- a/proto/bgp/bgp.h +++ b/proto/bgp/bgp.h @@ -582,6 +582,7 @@ int bgp_rte_better(struct rte *, struct rte *); 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); diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c index 03b16350..43b8f037 100644 --- a/proto/ospf/ospf.c +++ b/proto/ospf/ospf.c @@ -113,6 +113,7 @@ static void ospf_store_tmp_attrs(struct rte *rt, struct linpool *pool); 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); @@ -382,6 +383,7 @@ ospf_init(struct proto_config *CF) 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; } @@ -419,6 +421,11 @@ ospf_rte_same(struct rte *new, struct rte *old) 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) diff --git a/proto/rip/rip.c b/proto/rip/rip.c index f2e56e93..2653b23b 100644 --- a/proto/rip/rip.c +++ b/proto/rip/rip.c @@ -1098,6 +1098,11 @@ rip_rte_same(struct rte *new, struct rte *old) (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) @@ -1124,6 +1129,7 @@ rip_init(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; }