summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaria Matejka <mq@ucw.cz>2021-03-20 23:18:34 +0100
committerMaria Matejka <mq@ucw.cz>2021-10-13 19:09:04 +0200
commitd471d5fc7ce587ed836ca7fa10a79331bc181d45 (patch)
tree557c529dde26bf83da31b5ddcacd5d842d9421bd
parent5cff1d5f022755df61af6fc21cc4f2e5d384404e (diff)
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.
-rw-r--r--nest/protocol.h1
-rw-r--r--nest/rt-table.c36
-rw-r--r--proto/babel/babel.c7
-rw-r--r--proto/bgp/attrs.c7
-rw-r--r--proto/bgp/bgp.c1
-rw-r--r--proto/bgp/bgp.h1
-rw-r--r--proto/ospf/ospf.c7
-rw-r--r--proto/rip/rip.c6
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;
}