summaryrefslogtreecommitdiff
path: root/proto/static
diff options
context:
space:
mode:
Diffstat (limited to 'proto/static')
-rw-r--r--proto/static/config.Y19
-rw-r--r--proto/static/static.c30
-rw-r--r--proto/static/static.h1
3 files changed, 44 insertions, 6 deletions
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 */
};