summaryrefslogtreecommitdiff
path: root/sysdep/unix
diff options
context:
space:
mode:
authorMartin Mares <mj@ucw.cz>1998-12-08 18:37:58 +0000
committerMartin Mares <mj@ucw.cz>1998-12-08 18:37:58 +0000
commit8e66a0ebb927f40c9fcb48bbf5f2d811d7b7c7f3 (patch)
tree48925711f0a9e8a943f54a190065668d2edefe72 /sysdep/unix
parent980297d2899a5aec6609d1f7b44626e52e6e4417 (diff)
Hopefully finished kernel syncer (krt) rewrite:
o Interface syncing is now a part of krt and it can have configurable parameters. Actually, the only one is scan rate now :) o Kernel routing table syncing is now synchronized with interface syncing (we need the most recent version of the interface list to prevent lots of routes to non-existent destinations from appearing). Instead of its own timer, we just check if it's route scan time after each iface list scan. o Syncing of device routes implemented. o CONFIG_AUTO_ROUTES should control syncing of automatic device routes. o Rewrote krt_remove_route() to really remove routes :) o Better diagnostics. o Fixed a couple of bugs.
Diffstat (limited to 'sysdep/unix')
-rw-r--r--sysdep/unix/Modules2
-rw-r--r--sysdep/unix/krt-iface.Y30
-rw-r--r--sysdep/unix/krt-iface.h16
-rw-r--r--sysdep/unix/krt-set.c74
-rw-r--r--sysdep/unix/krt.h9
-rw-r--r--sysdep/unix/sync-if.c38
-rw-r--r--sysdep/unix/sync-rt.c3
7 files changed, 133 insertions, 39 deletions
diff --git a/sysdep/unix/Modules b/sysdep/unix/Modules
index 441c3f07..f6db6d35 100644
--- a/sysdep/unix/Modules
+++ b/sysdep/unix/Modules
@@ -9,3 +9,5 @@ krt.Y
krt.h
krt-set.c
krt-set.h
+krt-iface.h
+krt-iface.Y
diff --git a/sysdep/unix/krt-iface.Y b/sysdep/unix/krt-iface.Y
new file mode 100644
index 00000000..becb70cf
--- /dev/null
+++ b/sysdep/unix/krt-iface.Y
@@ -0,0 +1,30 @@
+/*
+ * BIRD -- UNIX Interface Syncer Configuration
+ *
+ * (c) 1998 Martin Mares <mj@ucw.cz>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+CF_HDR
+
+#include "lib/krt-scan.h"
+
+CF_DECLS
+
+CF_KEYWORDS(LEARN, ROUTE, SCAN, TIME)
+
+CF_GRAMMAR
+
+CF_ADDTO(kern_proto, kern_proto krt_if_item ';')
+
+krt_if_item:
+ SCAN TIME expr {
+ /* Scan time of 0 means scan on startup only */
+ ((struct krt_proto *) this_proto)->ifopt.scan_time = $3;
+ }
+ ;
+
+CF_CODE
+
+CF_END
diff --git a/sysdep/unix/krt-iface.h b/sysdep/unix/krt-iface.h
new file mode 100644
index 00000000..95cfff8c
--- /dev/null
+++ b/sysdep/unix/krt-iface.h
@@ -0,0 +1,16 @@
+/*
+ * BIRD -- Unix Kernel Interface Syncer -- Setting Parameters
+ *
+ * (c) 1998 Martin Mares <mj@ucw.cz>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#ifndef _BIRD_KRT_IFACE_H_
+#define _BIRD_KRT_IFACE_H_
+
+struct krt_if_params {
+ int scan_time;
+};
+
+#endif
diff --git a/sysdep/unix/krt-set.c b/sysdep/unix/krt-set.c
index 8bc2df11..33d5bca0 100644
--- a/sysdep/unix/krt-set.c
+++ b/sysdep/unix/krt-set.c
@@ -29,9 +29,7 @@ krt_capable(rte *e)
return
a->cast == RTC_UNICAST &&
(a->dest == RTD_ROUTER
-#ifndef CONFIG_AUTO_ROUTES
|| a->dest == RTD_DEVICE
-#endif
#ifdef RTF_REJECT
|| a->dest == RTD_UNREACHABLE
#endif
@@ -39,38 +37,25 @@ krt_capable(rte *e)
!a->tos;
}
-void
-krt_remove_route(rte *old)
+static inline int
+krt_capable_op(rte *e)
{
- net *net = old->net;
- struct rtentry re;
+ rta *a = e->attrs;
- if (!krt_capable(old) || old->attrs->source == RTS_INHERIT)
- {
- DBG("krt_remove_route(ignored %I/%d)\n", net->n.prefix, net->n.pxlen);
- return;
- }
- DBG("krt_remove_route(%I/%d)\n", net->n.prefix, net->n.pxlen);
- bzero(&re, sizeof(re));
- fill_in_sockaddr((struct sockaddr_in *) &re.rt_dst, net->n.prefix, 0);
- fill_in_sockaddr((struct sockaddr_in *) &re.rt_genmask, ipa_mkmask(net->n.pxlen), 0);
- if (ioctl(if_scan_sock, SIOCDELRT, &re) < 0)
- log(L_ERR "SIOCDELRT(%I/%d): %m", net->n.prefix, net->n.pxlen);
+#ifdef CONFIG_AUTO_ROUTES
+ if (a->dest == RTD_ROUTER && a->source == RTS_DEVICE)
+ return 0;
+#endif
+ return krt_capable(e);
}
-void
-krt_add_route(rte *new)
+static void
+krt_ioctl(int ioc, rte *e, char *name)
{
- net *net = new->net;
+ net *net = e->net;
struct rtentry re;
- rta *a = new->attrs;
+ rta *a = e->attrs;
- if (!krt_capable(new) || new->attrs->source == RTS_INHERIT)
- {
- DBG("krt_add_route(ignored %I/%d)\n", net->n.prefix, net->n.pxlen);
- return;
- }
- DBG("krt_add_route(%I/%d)\n", net->n.prefix, net->n.pxlen);
bzero(&re, sizeof(re));
fill_in_sockaddr((struct sockaddr_in *) &re.rt_dst, net->n.prefix, 0);
fill_in_sockaddr((struct sockaddr_in *) &re.rt_genmask, ipa_mkmask(net->n.pxlen), 0);
@@ -83,11 +68,9 @@ krt_add_route(rte *new)
fill_in_sockaddr((struct sockaddr_in *) &re.rt_gateway, a->gw, 0);
re.rt_flags |= RTF_GATEWAY;
break;
-#ifndef CONFIG_AUTO_ROUTES
case RTD_DEVICE:
re.rt_dev = a->iface->name;
break;
-#endif
#ifdef RTF_REJECT
case RTD_UNREACHABLE:
re.rt_flags |= RTF_REJECT;
@@ -97,8 +80,36 @@ krt_add_route(rte *new)
die("krt set: unknown flags, but not filtered");
}
- if (ioctl(if_scan_sock, SIOCADDRT, &re) < 0)
- log(L_ERR "SIOCADDRT(%I/%d): %m", net->n.prefix, net->n.pxlen);
+ if (ioctl(if_scan_sock, ioc, &re) < 0)
+ log(L_ERR "%s(%I/%d): %m", name, net->n.prefix, net->n.pxlen);
+}
+
+void
+krt_remove_route(rte *old)
+{
+ net *net = old->net;
+
+ if (!krt_capable_op(old))
+ {
+ DBG("krt_remove_route(ignored %I/%d)\n", net->n.prefix, net->n.pxlen);
+ return;
+ }
+ DBG("krt_remove_route(%I/%d)\n", net->n.prefix, net->n.pxlen);
+ krt_ioctl(SIOCDELRT, old, "SIOCDELRT");
+}
+
+void
+krt_add_route(rte *new)
+{
+ net *net = new->net;
+
+ if (!krt_capable_op(new))
+ {
+ DBG("krt_add_route(ignored %I/%d)\n", net->n.prefix, net->n.pxlen);
+ return;
+ }
+ DBG("krt_add_route(%I/%d)\n", net->n.prefix, net->n.pxlen);
+ krt_ioctl(SIOCADDRT, new, "SIOCADDRT");
}
void
@@ -119,4 +130,3 @@ krt_set_preconfig(struct krt_proto *x)
die("krt set: missing socket");
x->p.rt_notify = krt_set_notify;
}
-
diff --git a/sysdep/unix/krt.h b/sysdep/unix/krt.h
index aae5bd57..4ea88d50 100644
--- a/sysdep/unix/krt.h
+++ b/sysdep/unix/krt.h
@@ -11,6 +11,7 @@
#include "lib/krt-scan.h"
#include "lib/krt-set.h"
+#include "lib/krt-iface.h"
/* Flags stored in net->n.flags */
@@ -28,6 +29,7 @@ struct krt_proto {
struct proto p;
struct krt_set_params setopt;
struct krt_scan_params scanopt;
+ struct krt_if_params ifopt;
};
extern struct proto *cf_krt_proto;
@@ -37,9 +39,16 @@ extern struct proto *cf_krt_proto;
void krt_scan_preconfig(struct krt_proto *);
void krt_scan_start(struct krt_proto *);
void krt_scan_shutdown(struct krt_proto *);
+void krt_scan_ifaces_done(struct krt_proto *);
/* krt-set.c */
void krt_set_preconfig(struct krt_proto *);
+/* sync-if.c */
+
+void krt_if_preconfig(struct krt_proto *);
+void krt_if_start(struct krt_proto *);
+void krt_if_shutdown(struct krt_proto *);
+
#endif
diff --git a/sysdep/unix/sync-if.c b/sysdep/unix/sync-if.c
index 76426e73..70a2c0ce 100644
--- a/sysdep/unix/sync-if.c
+++ b/sysdep/unix/sync-if.c
@@ -17,12 +17,14 @@
#include "nest/bird.h"
#include "nest/iface.h"
+#include "nest/route.h"
+#include "nest/protocol.h"
#include "lib/timer.h"
+#include "lib/krt.h"
#include "unix.h"
int if_scan_sock;
-int if_scan_period = 60;
static timer *if_scan_timer;
@@ -131,8 +133,9 @@ scan_if(timer *t)
struct ifconf ic;
static int last_ifbuf_size = 4*sizeof(struct ifreq);
int res;
+ struct krt_proto *p = t->data;
- DBG("Scanning interfaces...\n");
+ DBG("It's interface scan time...\n");
for(;;)
{
if (last_ifbuf_size)
@@ -165,6 +168,32 @@ scan_if(timer *t)
DBG("Increased ifconf buffer size to %d\n", last_ifbuf_size);
#endif
}
+ krt_scan_ifaces_done(p);
+}
+
+void
+krt_if_start(struct krt_proto *p)
+{
+ if_scan_timer = tm_new(&root_pool);
+ if_scan_timer->hook = scan_if;
+ if_scan_timer->data = p;
+ if_scan_timer->recurrent = p->ifopt.scan_time;
+ scan_if(if_scan_timer);
+ tm_start(if_scan_timer, p->ifopt.scan_time);
+}
+
+void
+krt_if_preconfig(struct krt_proto *p)
+{
+ p->ifopt.scan_time = 60;
+}
+
+void
+krt_if_shutdown(struct krt_proto *p)
+{
+ tm_stop(if_scan_timer);
+ rfree(if_scan_timer);
+ /* FIXME: What should we do with interfaces? */
}
void
@@ -174,9 +203,4 @@ scan_if_init(void)
DBG("Using socket %d for interface and route scanning\n", if_scan_sock);
if (if_scan_sock < 0)
die("Cannot create scanning socket: %m");
- scan_if(NULL);
- if_scan_timer = tm_new(&root_pool);
- if_scan_timer->hook = scan_if;
- if_scan_timer->recurrent = if_scan_period;
- tm_start(if_scan_timer, if_scan_period);
}
diff --git a/sysdep/unix/sync-rt.c b/sysdep/unix/sync-rt.c
index 169494e2..dc79118d 100644
--- a/sysdep/unix/sync-rt.c
+++ b/sysdep/unix/sync-rt.c
@@ -30,6 +30,7 @@ krt_start(struct proto *P)
{
struct krt_proto *p = (struct krt_proto *) P;
krt_scan_start(p);
+ krt_if_start(p);
}
void
@@ -37,6 +38,7 @@ krt_shutdown(struct proto *P, int time)
{
struct krt_proto *p = (struct krt_proto *) P;
krt_scan_shutdown(p);
+ krt_if_shutdown(p);
}
void
@@ -50,6 +52,7 @@ krt_preconfig(struct protocol *x)
p->p.shutdown = krt_shutdown;
krt_scan_preconfig(p);
krt_set_preconfig(p);
+ krt_if_preconfig(p);
}
struct protocol proto_unix_kernel = {