]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
All static routes except for device ones should work and appear/disappear
authorMartin Mares <mj@ucw.cz>
Sun, 6 Dec 1998 23:13:31 +0000 (23:13 +0000)
committerMartin Mares <mj@ucw.cz>
Sun, 6 Dec 1998 23:13:31 +0000 (23:13 +0000)
when their destination comes on/off link. Deserves better testing :)

See example in bird.conf.

TODO
bird.conf
proto/static/config.Y
proto/static/static.c
proto/static/static.h

diff --git a/TODO b/TODO
index 105058234c5da0964ef28b67c4340ecd750ee92f..6298a53f11c509df89d4d622af917ad0f0fb0c57 100644 (file)
--- a/TODO
+++ b/TODO
@@ -18,6 +18,10 @@ Core
 - check if all protocols set proper packet priorities and TTL's.
 - better default protocol names
 - config: comments at end of line -> explicit ';' needed?
+- remove post-config hooks?
+
+- static: check validity of route destination?
+- static: device routes
 
 - filter: logging of dropped routes (?)
 - limitation of memory consumption: per-process and total (?)
index 30c0ea2754d248f99321007eb46014f6ed625fcc..1d1c39af5e7dde434ab2c627655483884b8a3cee 100644 (file)
--- a/bird.conf
+++ b/bird.conf
@@ -25,5 +25,8 @@ protocol kernel {
 }
 
 protocol static {
-       disabled
+#      disabled
+#      route 10.0.0.0/8 reject
+#      route 10.1.0.0:255.255.255.0 via 62.168.0.3
+#      route 10.2.0.0/24 via "arc0"
 }
index a9eaa87253803693f4980dedb27b99730db83230..ff5065112ae1180324322ef574931725077fcf04 100644 (file)
@@ -10,9 +10,11 @@ CF_HDR
 
 #include "proto/static/static.h"
 
+static struct static_route *this_srt;
+
 CF_DECLS
 
-CF_KEYWORDS(STATIC)
+CF_KEYWORDS(STATIC, ROUTE, VIA, DROP, REJECT, PROHIBIT, PREFERENCE)
 
 CF_GRAMMAR
 
@@ -27,6 +29,32 @@ static_proto_start: proto_start STATIC {
 static_proto:
    static_proto_start proto_name '{'
  | static_proto proto_item ';'
+ | static_proto stat_route ';'
+ ;
+
+stat_route0: ROUTE IPA pxlen {
+     this_srt = cfg_allocz(sizeof(struct static_route));
+     add_tail(&((struct static_proto *) this_proto)->other_routes, &this_srt->n);
+     if (!ip_is_prefix($2, $3)) cf_error("Invalid network prefix: %I/%d", $2, $3);
+     this_srt->net = $2;
+     this_srt->masklen = $3;
+  }
+ ;
+
+stat_route:
+   stat_route0 VIA IPA {
+      this_srt->dest = RTD_ROUTER;
+      this_srt->via = $3;
+   }
+ | stat_route0 VIA TEXT {
+      this_srt->dest = RTD_DEVICE;
+      this_srt->if_name = $3;
+      rem_node(&this_srt->n);
+      add_tail(&((struct static_proto *) this_proto)->iface_routes, &this_srt->n);
+   }
+ | stat_route0 DROP { this_srt->dest = RTD_BLACKHOLE; }
+ | stat_route0 REJECT { this_srt->dest = RTD_UNREACHABLE; }
+ | stat_route0 PROHIBIT { this_srt->dest = RTD_PROHIBIT; }
  ;
 
 CF_CODE
index 679ee6eefa89c3db6a40af895335d0232893e7de..bc060cda0172b311ba93662a9ae2c9df173e8be7 100644 (file)
@@ -8,6 +8,8 @@
 
 #define LOCAL_DEBUG
 
+#include <string.h>
+
 #include "nest/bird.h"
 #include "nest/iface.h"
 #include "nest/protocol.h"
 
 #define GET_DATA struct static_proto *p = (struct static_proto *) P
 
+static void
+static_install(struct static_proto *p, struct static_route *r, struct iface *ifa)
+{
+  net *n;
+  rta a, *aa;
+  rte *e;
+
+  DBG("Installing static route %I/%d, rtd=%d\n", r->net, r->masklen, r->dest);
+  bzero(&a, sizeof(a));
+  a.proto = &p->p;
+  a.source = (r->dest == RTD_DEVICE) ? RTS_STATIC_DEVICE : RTS_STATIC;
+  a.scope = SCOPE_UNIVERSE;
+  a.cast = RTC_UNICAST;
+  a.dest = r->dest;
+  a.tos = 0;
+  a.gw = r->via;
+  a.iface = ifa;
+  aa = rta_lookup(&a);
+
+  n = net_get(&master_table, a.tos, r->net, r->masklen);
+  e = rte_get_temp(aa);
+  e->net = n;
+  e->pflags = 0;
+  rte_update(n, &p->p, e);
+}
+
+static void
+static_remove(struct static_proto *p, struct static_route *r)
+{
+  net *n;
+
+  DBG("Removing static route %I/%d\n", r->net, r->masklen);
+  n = net_find(&master_table, 0, r->net, r->masklen);
+  if (n)
+    rte_update(n, &p->p, NULL);
+}
+
 static void
 static_start(struct proto *P)
 {
+  GET_DATA;
+  struct static_route *r;
+
   DBG("Static: take off!\n");
+  WALK_LIST(r, p->other_routes)
+    if (r->dest == RTD_ROUTER)
+      {
+       struct neighbor *n = neigh_find(P, &r->via, NEF_STICKY);
+       if (n)
+         {
+           n->data = r;
+           r->neigh = n;
+           static_install(p, r, n->iface);
+         }
+       else
+         log(L_ERR "Static route destination %I is invalid. Ignoring.\n", r->via);
+      }
+    else
+      static_install(p, r, NULL);
 }
 
 static void
 static_neigh_notify(struct neighbor *n)
 {
-  DBG("Static: neighbor notify got, don't know why.\n");
+  DBG("Static: neighbor notify for %I: iface %p\n", n->addr, n->iface);
+  if (n->iface)
+    static_install((struct static_proto *) n->proto, n->data, n->iface);
+  else
+    static_remove((struct static_proto *) n->proto, n->data);
+}
+
+static void
+static_dump_rt(struct static_route *r)
+{
+  debug("%16I/%2d: ", r->net, r->masklen);
+  switch (r->dest)
+    {
+    case RTD_ROUTER:
+      debug("via %I\n", r->via);
+      break;
+    case RTD_DEVICE:
+      debug("dev %s\n", r->if_name);
+      break;
+    default:
+      debug("rtd %d\n", r->dest);
+      break;
+    }
 }
 
 static void
 static_dump(struct proto *P)
 {
-  DBG("Static: no dumps available in demo version.\n");
+  GET_DATA;
+  struct static_route *r;
+
+  debug("Independent static routes:\n");
+  WALK_LIST(r, p->other_routes)
+    static_dump_rt(r);
+  debug("Device static routes:\n");
+  WALK_LIST(r, p->iface_routes)
+    static_dump_rt(r);
 }
 
 void
@@ -45,7 +132,8 @@ static_init_instance(struct static_proto *P)
   p->start = static_start;
   p->neigh_notify = static_neigh_notify;
   p->dump = static_dump;
-  /* FIXME: Should shutdown remove all routes? */
+  init_list(&P->iface_routes);
+  init_list(&P->other_routes);
 }
 
 static void
index df18c133f5a362d3082bb53f3ed3784e860c452f..b6d69457ec07c8a2cafe07b8eb3480423d0a98a2 100644 (file)
 
 struct static_proto {
   struct proto p;
-  list routes;
+  list iface_routes;                   /* Routes to search on interface events */
+  list other_routes;                   /* Routes hooked to neighbor cache and reject routes */
 };
 
 void static_init_instance(struct static_proto *);
 
 struct static_route {
   node n;
-  u32 net;                             /* Network we route */
+  ip_addr net;                         /* Network we route */
   int masklen;                         /* Mask length */
   int dest;                            /* Destination type (RTD_*) */
-  u32 via;                             /* Destination router */
+  ip_addr via;                         /* Destination router */
   struct neighbor *neigh;
-  /* FIXME: Device routes, maybe via device patterns? */
-  /* FIXME: More route attributes, probably via filter syntax */
+  byte *if_name;                       /* Name for RTD_DEVICE routes */
 };
 
 #endif