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; };
This commit is contained in:
parent
ffa398b8d8
commit
1321e12ac4
6 changed files with 83 additions and 9 deletions
|
@ -1527,6 +1527,30 @@ f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struc
|
||||||
return res.val.i;
|
return res.val.i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: perhaps we could integrate f_eval(), f_eval_rte() and f_run() */
|
||||||
|
|
||||||
|
struct f_val
|
||||||
|
f_eval_rte(struct f_inst *expr, struct rte **rte, struct linpool *tmp_pool)
|
||||||
|
{
|
||||||
|
struct ea_list *tmp_attrs = NULL;
|
||||||
|
|
||||||
|
f_rte = rte;
|
||||||
|
f_old_rta = NULL;
|
||||||
|
f_tmp_attrs = &tmp_attrs;
|
||||||
|
f_pool = tmp_pool;
|
||||||
|
f_flags = 0;
|
||||||
|
|
||||||
|
LOG_BUFFER_INIT(f_buf);
|
||||||
|
|
||||||
|
/* Note that in this function we assume that rte->attrs is private / uncached */
|
||||||
|
struct f_val res = interpret(expr);
|
||||||
|
|
||||||
|
/* Hack to include EAF_TEMP attributes to the main list */
|
||||||
|
(*rte)->attrs->eattrs = ea_append(tmp_attrs, (*rte)->attrs->eattrs);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
struct f_val
|
struct f_val
|
||||||
f_eval(struct f_inst *expr, struct linpool *tmp_pool)
|
f_eval(struct f_inst *expr, struct linpool *tmp_pool)
|
||||||
{
|
{
|
||||||
|
|
|
@ -107,6 +107,7 @@ struct ea_list;
|
||||||
struct rte;
|
struct rte;
|
||||||
|
|
||||||
int f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struct linpool *tmp_pool, int flags);
|
int f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struct linpool *tmp_pool, int flags);
|
||||||
|
struct f_val f_eval_rte(struct f_inst *expr, struct rte **rte, struct linpool *tmp_pool);
|
||||||
struct f_val f_eval(struct f_inst *expr, struct linpool *tmp_pool);
|
struct f_val f_eval(struct f_inst *expr, struct linpool *tmp_pool);
|
||||||
uint f_eval_int(struct f_inst *expr);
|
uint f_eval_int(struct f_inst *expr);
|
||||||
u32 f_eval_asn(struct f_inst *expr);
|
u32 f_eval_asn(struct f_inst *expr);
|
||||||
|
|
|
@ -450,10 +450,21 @@ ospf_import_control(struct proto *P, rte **new, ea_list **attrs, struct linpool
|
||||||
if (oa_is_stub(oa))
|
if (oa_is_stub(oa))
|
||||||
return -1; /* Do not export routes to stub areas */
|
return -1; /* Do not export routes to stub areas */
|
||||||
|
|
||||||
eattr *ea = ea_find(e->attrs->eattrs, EA_GEN_IGP_METRIC);
|
ea_list *ea = e->attrs->eattrs;
|
||||||
u32 m1 = (ea && (ea->u.data < LSINFINITY)) ? ea->u.data : LSINFINITY;
|
u32 m0 = ea_get_int(ea, EA_GEN_IGP_METRIC, LSINFINITY);
|
||||||
|
u32 m1 = MIN(m0, LSINFINITY);
|
||||||
|
u32 m2 = 10000;
|
||||||
|
u32 tag = 0;
|
||||||
|
|
||||||
*attrs = ospf_build_attrs(*attrs, pool, m1, 10000, 0, 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, m2, tag, 0);
|
||||||
return 0; /* Leave decision to the filters */
|
return 0; /* Leave decision to the filters */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ CF_DEFINES
|
||||||
|
|
||||||
#define STATIC_CFG ((struct static_config *) this_proto)
|
#define STATIC_CFG ((struct static_config *) this_proto)
|
||||||
static struct static_route *this_srt, *this_srt_nh, *last_srt_nh;
|
static struct static_route *this_srt, *this_srt_nh, *last_srt_nh;
|
||||||
|
static struct f_inst **this_srt_last_cmd;
|
||||||
|
|
||||||
CF_DECLS
|
CF_DECLS
|
||||||
|
|
||||||
|
@ -36,7 +37,7 @@ static_proto:
|
||||||
| static_proto proto_item ';'
|
| static_proto proto_item ';'
|
||||||
| static_proto CHECK LINK bool ';' { STATIC_CFG->check_link = $4; }
|
| static_proto CHECK LINK bool ';' { STATIC_CFG->check_link = $4; }
|
||||||
| static_proto IGP TABLE rtable ';' { STATIC_CFG->igp_table = $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 {
|
stat_route0: ROUTE prefix {
|
||||||
|
@ -44,6 +45,7 @@ stat_route0: ROUTE prefix {
|
||||||
add_tail(&STATIC_CFG->other_routes, &this_srt->n);
|
add_tail(&STATIC_CFG->other_routes, &this_srt->n);
|
||||||
this_srt->net = $2.addr;
|
this_srt->net = $2.addr;
|
||||||
this_srt->masklen = $2.len;
|
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_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]])
|
CF_CLI(SHOW STATIC, optsym, [<name>], [[Show details of static protocol]])
|
||||||
{ static_show(proto_get_named($3, &proto_static)); } ;
|
{ static_show(proto_get_named($3, &proto_static)); } ;
|
||||||
|
|
||||||
|
|
|
@ -42,11 +42,14 @@
|
||||||
#include "nest/route.h"
|
#include "nest/route.h"
|
||||||
#include "nest/cli.h"
|
#include "nest/cli.h"
|
||||||
#include "conf/conf.h"
|
#include "conf/conf.h"
|
||||||
|
#include "filter/filter.h"
|
||||||
#include "lib/string.h"
|
#include "lib/string.h"
|
||||||
#include "lib/alloca.h"
|
#include "lib/alloca.h"
|
||||||
|
|
||||||
#include "static.h"
|
#include "static.h"
|
||||||
|
|
||||||
|
static linpool *static_lp;
|
||||||
|
|
||||||
static inline rtable *
|
static inline rtable *
|
||||||
p_igp_table(struct proto *p)
|
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;
|
return cf->igp_table ? cf->igp_table->table : p->table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
static_install(struct proto *p, struct static_route *r, struct iface *ifa)
|
static_install(struct proto *p, struct static_route *r, struct iface *ifa)
|
||||||
{
|
{
|
||||||
net *n;
|
net *n;
|
||||||
rta a, *aa;
|
rta a;
|
||||||
rte *e;
|
rte *e;
|
||||||
|
|
||||||
if (r->installed > 0)
|
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)
|
if (r->dest == RTDX_RECURSIVE)
|
||||||
rta_set_recursive_next_hop(p->table, &a, p_igp_table(p), &r->via, &r->via);
|
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);
|
n = net_get(p->table, r->net, r->masklen);
|
||||||
e = rte_get_temp(aa);
|
e = rte_get_temp(&a);
|
||||||
e->net = n;
|
e->net = n;
|
||||||
e->pflags = 0;
|
e->pflags = 0;
|
||||||
|
|
||||||
|
if (r->cmds)
|
||||||
|
f_eval_rte(r->cmds, &e, static_lp);
|
||||||
|
|
||||||
rte_update(p, n, e);
|
rte_update(p, n, e);
|
||||||
r->installed = 1;
|
r->installed = 1;
|
||||||
|
|
||||||
|
if (r->cmds)
|
||||||
|
lp_flush(static_lp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -220,6 +230,9 @@ static_start(struct proto *p)
|
||||||
|
|
||||||
DBG("Static: take off!\n");
|
DBG("Static: take off!\n");
|
||||||
|
|
||||||
|
if (!static_lp)
|
||||||
|
static_lp = lp_new(&root_pool, 1008);
|
||||||
|
|
||||||
if (cf->igp_table)
|
if (cf->igp_table)
|
||||||
rt_lock_table(cf->igp_table->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 void
|
||||||
static_match(struct proto *p, struct static_route *r, struct static_config *n)
|
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:
|
found:
|
||||||
/* If destination is different, force reinstall */
|
/* 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;
|
t->installed = -1;
|
||||||
else
|
else
|
||||||
t->installed = r->installed;
|
t->installed = r->installed;
|
||||||
|
|
|
@ -31,6 +31,7 @@ struct static_route {
|
||||||
struct neighbor *neigh;
|
struct neighbor *neigh;
|
||||||
byte *if_name; /* Name for RTD_DEVICE routes */
|
byte *if_name; /* Name for RTD_DEVICE routes */
|
||||||
struct static_route *mp_next; /* Nexthops for RTD_MULTIPATH 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 */
|
int installed; /* Installed in rt table, -1 for reinstall */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue