]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Static: Allows to specify attributes for static routes
authorOndrej Zajicek <santiago@crfreenet.org>
Mon, 20 Jul 2015 09:12:02 +0000 (11:12 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Mon, 20 Jul 2015 15:11:10 +0000 (17:11 +0200)
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; };

filter/filter.c
filter/filter.h
proto/ospf/ospf.c
proto/static/config.Y
proto/static/static.c
proto/static/static.h

index 3f8968aa132fbcc58687e9b760f897f497f580c7..55062acadec94f9309ca21588630876a460da6e5 100644 (file)
@@ -1527,6 +1527,30 @@ f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struc
   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
 f_eval(struct f_inst *expr, struct linpool *tmp_pool)
 {
index 2b2d23c2fb40f5d0e585d0fd613dc84f2326010d..e59c822602c2f7f474cce90d902c85d3a251bd72 100644 (file)
@@ -107,6 +107,7 @@ struct ea_list;
 struct rte;
 
 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);
 uint f_eval_int(struct f_inst *expr);
 u32 f_eval_asn(struct f_inst *expr);
index 1bc4e077c216eaafa6506def2aa6db92245aac38..d5d5d354bff2ddd66b029a6fd790bc34e175a6f7 100644 (file)
@@ -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 */
 }
 
index a8bfa36fa6f057f8bb628c1657be40e6c576af12..d1b62af972ec2a168bd167b30694850db5419094 100644 (file)
@@ -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)); } ;
 
index e7e7ab153cf362381d97185a75947f701f8eee3e..57c44885631864406dd78cece935c6d20372ab98 100644 (file)
 #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;
index 99a0e68b252af9d47b794397cbce083af6c1b7c0..f197d3520586480a5bb42dacc519796296dfa42a 100644 (file)
@@ -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 */
 };