diff options
author | Ondrej Zajicek <santiago@crfreenet.org> | 2015-07-20 11:12:02 +0200 |
---|---|---|
committer | Ondrej Zajicek <santiago@crfreenet.org> | 2015-07-20 17:11:10 +0200 |
commit | 1321e12ac460bd542d3946a0c4a4dacd71157cfa (patch) | |
tree | 7f9470375fdc8fb4bf8c4b76140c6e4686d7e079 /proto | |
parent | ffa398b8d8bac4cf6368fe700466cad4ff12fee8 (diff) |
Static: Allows to specify attributes for static routes
The patch adds suport for specifying route attributes together with
static routes, e.g.:
route 10.1.1.0/24 via 10.0.0.1 { krt_advmss = 1200; ospf_metric1 = 100; };
Diffstat (limited to 'proto')
-rw-r--r-- | proto/ospf/ospf.c | 17 | ||||
-rw-r--r-- | proto/static/config.Y | 19 | ||||
-rw-r--r-- | proto/static/static.c | 30 | ||||
-rw-r--r-- | proto/static/static.h | 1 |
4 files changed, 58 insertions, 9 deletions
diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c index 1bc4e077..d5d5d354 100644 --- a/proto/ospf/ospf.c +++ b/proto/ospf/ospf.c @@ -450,10 +450,21 @@ ospf_import_control(struct proto *P, rte **new, ea_list **attrs, struct linpool if (oa_is_stub(oa)) return -1; /* Do not export routes to stub areas */ - eattr *ea = ea_find(e->attrs->eattrs, EA_GEN_IGP_METRIC); - u32 m1 = (ea && (ea->u.data < LSINFINITY)) ? ea->u.data : LSINFINITY; + ea_list *ea = e->attrs->eattrs; + u32 m0 = ea_get_int(ea, EA_GEN_IGP_METRIC, LSINFINITY); + u32 m1 = MIN(m0, LSINFINITY); + u32 m2 = 10000; + u32 tag = 0; + + /* Hack for setting attributes directly in static protocol */ + if (e->attrs->source == RTS_STATIC) + { + m1 = ea_get_int(ea, EA_OSPF_METRIC1, m1); + m2 = ea_get_int(ea, EA_OSPF_METRIC2, 10000); + tag = ea_get_int(ea, EA_OSPF_TAG, 0); + } - *attrs = ospf_build_attrs(*attrs, pool, m1, 10000, 0, 0); + *attrs = ospf_build_attrs(*attrs, pool, m1, m2, tag, 0); return 0; /* Leave decision to the filters */ } diff --git a/proto/static/config.Y b/proto/static/config.Y index a8bfa36f..d1b62af9 100644 --- a/proto/static/config.Y +++ b/proto/static/config.Y @@ -14,6 +14,7 @@ CF_DEFINES #define STATIC_CFG ((struct static_config *) this_proto) static struct static_route *this_srt, *this_srt_nh, *last_srt_nh; +static struct f_inst **this_srt_last_cmd; CF_DECLS @@ -36,7 +37,7 @@ static_proto: | static_proto proto_item ';' | static_proto CHECK LINK bool ';' { STATIC_CFG->check_link = $4; } | static_proto IGP TABLE rtable ';' { STATIC_CFG->igp_table = $4; } - | static_proto stat_route ';' + | static_proto stat_route stat_route_opt_list ';' ; stat_route0: ROUTE prefix { @@ -44,6 +45,7 @@ stat_route0: ROUTE prefix { add_tail(&STATIC_CFG->other_routes, &this_srt->n); this_srt->net = $2.addr; this_srt->masklen = $2.len; + this_srt_last_cmd = &(this_srt->cmds); } ; @@ -94,6 +96,21 @@ stat_route: | stat_route0 PROHIBIT { this_srt->dest = RTD_PROHIBIT; } ; +stat_route_item: + cmd { *this_srt_last_cmd = $1; this_srt_last_cmd = &($1->next); } + ; + +stat_route_opts: + /* empty */ + | stat_route_opts stat_route_item + ; + +stat_route_opt_list: + /* empty */ + | '{' stat_route_opts '}' + ; + + CF_CLI(SHOW STATIC, optsym, [<name>], [[Show details of static protocol]]) { static_show(proto_get_named($3, &proto_static)); } ; diff --git a/proto/static/static.c b/proto/static/static.c index e7e7ab15..57c44885 100644 --- a/proto/static/static.c +++ b/proto/static/static.c @@ -42,11 +42,14 @@ #include "nest/route.h" #include "nest/cli.h" #include "conf/conf.h" +#include "filter/filter.h" #include "lib/string.h" #include "lib/alloca.h" #include "static.h" +static linpool *static_lp; + static inline rtable * p_igp_table(struct proto *p) { @@ -54,12 +57,11 @@ p_igp_table(struct proto *p) return cf->igp_table ? cf->igp_table->table : p->table; } - static void static_install(struct proto *p, struct static_route *r, struct iface *ifa) { net *n; - rta a, *aa; + rta a; rte *e; if (r->installed > 0) @@ -108,13 +110,21 @@ static_install(struct proto *p, struct static_route *r, struct iface *ifa) if (r->dest == RTDX_RECURSIVE) rta_set_recursive_next_hop(p->table, &a, p_igp_table(p), &r->via, &r->via); - aa = rta_lookup(&a); + /* We skip rta_lookup() here */ + n = net_get(p->table, r->net, r->masklen); - e = rte_get_temp(aa); + e = rte_get_temp(&a); e->net = n; e->pflags = 0; + + if (r->cmds) + f_eval_rte(r->cmds, &e, static_lp); + rte_update(p, n, e); r->installed = 1; + + if (r->cmds) + lp_flush(static_lp); } static void @@ -220,6 +230,9 @@ static_start(struct proto *p) DBG("Static: take off!\n"); + if (!static_lp) + static_lp = lp_new(&root_pool, 1008); + if (cf->igp_table) rt_lock_table(cf->igp_table->table); @@ -413,6 +426,13 @@ static_same_dest(struct static_route *x, struct static_route *y) } } +static inline int +static_same_rte(struct static_route *x, struct static_route *y) +{ + return static_same_dest(x, y) && i_same(x->cmds, y->cmds); +} + + static void static_match(struct proto *p, struct static_route *r, struct static_config *n) { @@ -441,7 +461,7 @@ static_match(struct proto *p, struct static_route *r, struct static_config *n) found: /* If destination is different, force reinstall */ - if ((r->installed > 0) && !static_same_dest(r, t)) + if ((r->installed > 0) && !static_same_rte(r, t)) t->installed = -1; else t->installed = r->installed; diff --git a/proto/static/static.h b/proto/static/static.h index 99a0e68b..f197d352 100644 --- a/proto/static/static.h +++ b/proto/static/static.h @@ -31,6 +31,7 @@ struct static_route { struct neighbor *neigh; byte *if_name; /* Name for RTD_DEVICE routes */ struct static_route *mp_next; /* Nexthops for RTD_MULTIPATH routes */ + struct f_inst *cmds; /* List of commands for setting attributes */ int installed; /* Installed in rt table, -1 for reinstall */ }; |