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.
This commit is contained in:
parent
980297d289
commit
8e66a0ebb9
12 changed files with 211 additions and 75 deletions
2
TODO
2
TODO
|
@ -16,9 +16,11 @@ Core
|
||||||
- default preferences of protocols: prefer BGP over OSPF/RIP external routes?
|
- default preferences of protocols: prefer BGP over OSPF/RIP external routes?
|
||||||
- secondary addresses -> subinterfaces
|
- secondary addresses -> subinterfaces
|
||||||
- check if all protocols set proper packet priorities and TTL's.
|
- check if all protocols set proper packet priorities and TTL's.
|
||||||
|
|
||||||
- better default protocol names
|
- better default protocol names
|
||||||
- config: comments at end of line -> explicit ';' needed?
|
- config: comments at end of line -> explicit ';' needed?
|
||||||
- remove post-config hooks?
|
- remove post-config hooks?
|
||||||
|
- command-line arguments: name of config file
|
||||||
|
|
||||||
- static: check validity of route destination?
|
- static: check validity of route destination?
|
||||||
- static: device routes
|
- static: device routes
|
||||||
|
|
|
@ -20,13 +20,18 @@ protocol device {
|
||||||
|
|
||||||
protocol kernel {
|
protocol kernel {
|
||||||
# disabled
|
# disabled
|
||||||
learn; # Learn all routes from the kernel
|
# learn; # Learn all routes from the kernel
|
||||||
scan time 10; # Scan kernel tables every 10 seconds
|
scan time 10; # Scan kernel tables every 10 seconds
|
||||||
|
# route scan time 20; # But routes only every 20 seconds
|
||||||
}
|
}
|
||||||
|
|
||||||
protocol static {
|
protocol static {
|
||||||
# disabled
|
# disabled
|
||||||
|
route 0.0.0.0/0 via 62.168.0.13
|
||||||
|
route 62.168.0.0/25 reject
|
||||||
# route 10.0.0.0/8 reject
|
# route 10.0.0.0/8 reject
|
||||||
# route 10.1.0.0:255.255.255.0 via 62.168.0.3
|
# route 10.1.1.0:255.255.255.0 via 62.168.0.3
|
||||||
|
# route 10.1.2.0:255.255.255.0 via 62.168.0.3
|
||||||
|
# route 10.1.3.0:255.255.255.0 via 62.168.0.4
|
||||||
# route 10.2.0.0/24 via "arc0"
|
# route 10.2.0.0/24 via "arc0"
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ CF_HDR
|
||||||
|
|
||||||
CF_DECLS
|
CF_DECLS
|
||||||
|
|
||||||
CF_KEYWORDS(LEARN, SCAN, TIME)
|
CF_KEYWORDS(LEARN, ROUTE, SCAN, TIME)
|
||||||
|
|
||||||
CF_GRAMMAR
|
CF_GRAMMAR
|
||||||
|
|
||||||
|
@ -22,9 +22,9 @@ krt_scan_item:
|
||||||
LEARN bool {
|
LEARN bool {
|
||||||
((struct krt_proto *) this_proto)->scanopt.learn = $2;
|
((struct krt_proto *) this_proto)->scanopt.learn = $2;
|
||||||
}
|
}
|
||||||
| SCAN TIME expr {
|
| ROUTE SCAN TIME expr {
|
||||||
/* Scan time of 0 means scan on startup only */
|
/* Scan time of 0 means scan on startup only */
|
||||||
((struct krt_proto *) this_proto)->scanopt.recurrence = $3;
|
((struct krt_proto *) this_proto)->scanopt.scan_time = $4;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <net/route.h>
|
#include <net/route.h>
|
||||||
|
@ -28,6 +29,22 @@ static int krt_scan_fd = -1;
|
||||||
|
|
||||||
/* FIXME: Filtering */
|
/* FIXME: Filtering */
|
||||||
|
|
||||||
|
struct iface *
|
||||||
|
krt_temp_iface(struct krt_proto *x, char *name)
|
||||||
|
{
|
||||||
|
SCANOPT;
|
||||||
|
struct iface *i;
|
||||||
|
|
||||||
|
WALK_LIST(i, p->temp_ifs)
|
||||||
|
if (!strcmp(i->name, name))
|
||||||
|
return i;
|
||||||
|
i = mb_alloc(x->p.pool, sizeof(struct iface));
|
||||||
|
bzero(i, sizeof(*i));
|
||||||
|
strcpy(i->name, name);
|
||||||
|
add_tail(&p->temp_ifs, &i->n);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
krt_uptodate(rte *k, rte *e)
|
krt_uptodate(rte *k, rte *e)
|
||||||
{
|
{
|
||||||
|
@ -35,10 +52,15 @@ krt_uptodate(rte *k, rte *e)
|
||||||
|
|
||||||
if (ka->dest != ea->dest)
|
if (ka->dest != ea->dest)
|
||||||
return 0;
|
return 0;
|
||||||
if (ka->dest == RTD_ROUTER && !ipa_equal(ka->gw, ea->gw))
|
switch (ka->dest)
|
||||||
return 0;
|
{
|
||||||
/* FIXME: Device routes */
|
case RTD_ROUTER:
|
||||||
|
return ipa_equal(ka->gw, ea->gw);
|
||||||
|
case RTD_DEVICE:
|
||||||
|
return !strcmp(ka->iface->name, ea->iface->name);
|
||||||
|
default:
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -76,7 +98,10 @@ krt_parse_entry(byte *ent, struct krt_proto *p)
|
||||||
DBG("Got %I/%d via %I flags %x\n", dest, masklen, gw, flags);
|
DBG("Got %I/%d via %I flags %x\n", dest, masklen, gw, flags);
|
||||||
|
|
||||||
if (!(flags & RTF_UP))
|
if (!(flags & RTF_UP))
|
||||||
|
{
|
||||||
|
DBG("Down.\n");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
if (flags & RTF_HOST)
|
if (flags & RTF_HOST)
|
||||||
masklen = 32;
|
masklen = 32;
|
||||||
if (flags & (RTF_DYNAMIC | RTF_MODIFIED)) /* Redirect route */
|
if (flags & (RTF_DYNAMIC | RTF_MODIFIED)) /* Redirect route */
|
||||||
|
@ -86,6 +111,13 @@ krt_parse_entry(byte *ent, struct krt_proto *p)
|
||||||
}
|
}
|
||||||
|
|
||||||
net = net_get(&master_table, 0, dest, masklen);
|
net = net_get(&master_table, 0, dest, masklen);
|
||||||
|
if (net->n.flags)
|
||||||
|
{
|
||||||
|
/* Route to this destination was already seen. Strange, but it happens... */
|
||||||
|
DBG("Already seen.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
a.proto = &p->p;
|
a.proto = &p->p;
|
||||||
a.source = RTS_INHERIT;
|
a.source = RTS_INHERIT;
|
||||||
a.scope = SCOPE_UNIVERSE;
|
a.scope = SCOPE_UNIVERSE;
|
||||||
|
@ -102,7 +134,7 @@ krt_parse_entry(byte *ent, struct krt_proto *p)
|
||||||
a.iface = ng->iface;
|
a.iface = ng->iface;
|
||||||
else
|
else
|
||||||
/* FIXME: Remove this warning? */
|
/* FIXME: Remove this warning? */
|
||||||
log(L_WARN "Kernel told us to use non-neighbor %I for %I/%d\n", gw, net->n.prefix, net->n.pxlen);
|
log(L_WARN "Kernel told us to use non-neighbor %I for %I/%d", gw, net->n.prefix, net->n.pxlen);
|
||||||
a.dest = RTD_ROUTER;
|
a.dest = RTD_ROUTER;
|
||||||
a.gw = gw;
|
a.gw = gw;
|
||||||
}
|
}
|
||||||
|
@ -111,10 +143,15 @@ krt_parse_entry(byte *ent, struct krt_proto *p)
|
||||||
a.dest = RTD_UNREACHABLE;
|
a.dest = RTD_UNREACHABLE;
|
||||||
a.gw = IPA_NONE;
|
a.gw = IPA_NONE;
|
||||||
}
|
}
|
||||||
|
else if (isalpha(iface[0]))
|
||||||
|
{
|
||||||
|
a.dest = RTD_DEVICE;
|
||||||
|
a.gw = IPA_NONE;
|
||||||
|
a.iface = krt_temp_iface(p, iface);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* FIXME: Should support interface routes? */
|
log(L_WARN "Kernel reporting unknown route type to %I/%d", net->n.prefix, net->n.pxlen);
|
||||||
/* FIXME: What about systems not generating their own if routes? (see CONFIG_AUTO_ROUTES) */
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,13 +172,14 @@ krt_parse_entry(byte *ent, struct krt_proto *p)
|
||||||
else
|
else
|
||||||
verdict = KRF_DELETE;
|
verdict = KRF_DELETE;
|
||||||
|
|
||||||
DBG("krt_parse_entry: verdict %d\n", verdict);
|
DBG("krt_parse_entry: verdict=%s\n", ((char *[]) { "CREATE", "SEEN", "UPDATE", "DELETE", "LEARN" }) [verdict]);
|
||||||
|
|
||||||
net->n.flags = verdict;
|
net->n.flags = verdict;
|
||||||
if (verdict != KRF_SEEN)
|
if (verdict != KRF_SEEN)
|
||||||
{
|
{
|
||||||
/* Get a cached copy of attributes and link the route */
|
/* Get a cached copy of attributes and link the route */
|
||||||
e->attrs = rta_lookup(e->attrs);
|
a.source = RTS_DUMMY;
|
||||||
|
e->attrs = rta_lookup(&a);
|
||||||
e->next = net->routes;
|
e->next = net->routes;
|
||||||
net->routes = e;
|
net->routes = e;
|
||||||
}
|
}
|
||||||
|
@ -155,7 +193,7 @@ krt_scan_proc(struct krt_proto *p)
|
||||||
byte buf[32768];
|
byte buf[32768];
|
||||||
int l, seen_hdr;
|
int l, seen_hdr;
|
||||||
|
|
||||||
DBG("Scanning kernel table...\n");
|
DBG("Scanning kernel routing table...\n");
|
||||||
if (krt_scan_fd < 0)
|
if (krt_scan_fd < 0)
|
||||||
{
|
{
|
||||||
krt_scan_fd = open("/proc/net/route", O_RDONLY);
|
krt_scan_fd = open("/proc/net/route", O_RDONLY);
|
||||||
|
@ -263,13 +301,18 @@ krt_prune(struct krt_proto *p)
|
||||||
FIB_WALK_END;
|
FIB_WALK_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
krt_scan_fire(timer *t)
|
krt_scan_ifaces_done(struct krt_proto *x)
|
||||||
{
|
{
|
||||||
struct krt_proto *p = t->data;
|
SCANOPT;
|
||||||
|
|
||||||
if (krt_scan_proc(p))
|
p->accum_time += x->ifopt.scan_time;
|
||||||
krt_prune(p);
|
if (p->scan_time && p->accum_time >= p->scan_time)
|
||||||
|
{
|
||||||
|
p->accum_time %= p->scan_time;
|
||||||
|
if (krt_scan_proc(x))
|
||||||
|
krt_prune(x);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -277,30 +320,21 @@ krt_scan_preconfig(struct krt_proto *x)
|
||||||
{
|
{
|
||||||
SCANOPT;
|
SCANOPT;
|
||||||
|
|
||||||
p->recurrence = 60;
|
p->scan_time = 1;
|
||||||
p->learn = 0;
|
p->learn = 0;
|
||||||
|
init_list(&p->temp_ifs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
krt_scan_start(struct krt_proto *x)
|
krt_scan_start(struct krt_proto *x)
|
||||||
{
|
{
|
||||||
SCANOPT;
|
SCANOPT;
|
||||||
timer *t = tm_new(x->p.pool);
|
|
||||||
|
|
||||||
p->timer = t;
|
/* Force krt scan after first interface scan */
|
||||||
t->hook = krt_scan_fire;
|
p->accum_time = p->scan_time - x->ifopt.scan_time;
|
||||||
t->data = x;
|
|
||||||
t->recurrent = p->recurrence;
|
|
||||||
krt_scan_fire(t);
|
|
||||||
if (t->recurrent)
|
|
||||||
tm_start(t, t->recurrent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
krt_scan_shutdown(struct krt_proto *x)
|
krt_scan_shutdown(struct krt_proto *x)
|
||||||
{
|
{
|
||||||
SCANOPT;
|
|
||||||
|
|
||||||
tm_stop(p->timer);
|
|
||||||
/* FIXME: Remove all krt's? */
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,9 +10,10 @@
|
||||||
#define _BIRD_KRT_SCAN_H_
|
#define _BIRD_KRT_SCAN_H_
|
||||||
|
|
||||||
struct krt_scan_params {
|
struct krt_scan_params {
|
||||||
int recurrence; /* How often should we scan krt, 0=only on startup */
|
|
||||||
int learn; /* Should we learn routes from the kernel? */
|
int learn; /* Should we learn routes from the kernel? */
|
||||||
struct timer *timer;
|
list temp_ifs; /* Temporary interfaces */
|
||||||
|
int scan_time; /* How often should we scan krt, 0=only on startup */
|
||||||
|
int accum_time; /* Accumulated scanning time */
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -9,3 +9,5 @@ krt.Y
|
||||||
krt.h
|
krt.h
|
||||||
krt-set.c
|
krt-set.c
|
||||||
krt-set.h
|
krt-set.h
|
||||||
|
krt-iface.h
|
||||||
|
krt-iface.Y
|
||||||
|
|
30
sysdep/unix/krt-iface.Y
Normal file
30
sysdep/unix/krt-iface.Y
Normal file
|
@ -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
|
16
sysdep/unix/krt-iface.h
Normal file
16
sysdep/unix/krt-iface.h
Normal file
|
@ -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
|
|
@ -29,9 +29,7 @@ krt_capable(rte *e)
|
||||||
return
|
return
|
||||||
a->cast == RTC_UNICAST &&
|
a->cast == RTC_UNICAST &&
|
||||||
(a->dest == RTD_ROUTER
|
(a->dest == RTD_ROUTER
|
||||||
#ifndef CONFIG_AUTO_ROUTES
|
|
||||||
|| a->dest == RTD_DEVICE
|
|| a->dest == RTD_DEVICE
|
||||||
#endif
|
|
||||||
#ifdef RTF_REJECT
|
#ifdef RTF_REJECT
|
||||||
|| a->dest == RTD_UNREACHABLE
|
|| a->dest == RTD_UNREACHABLE
|
||||||
#endif
|
#endif
|
||||||
|
@ -39,38 +37,25 @@ krt_capable(rte *e)
|
||||||
!a->tos;
|
!a->tos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static inline int
|
||||||
krt_remove_route(rte *old)
|
krt_capable_op(rte *e)
|
||||||
{
|
{
|
||||||
net *net = old->net;
|
rta *a = e->attrs;
|
||||||
struct rtentry re;
|
|
||||||
|
|
||||||
if (!krt_capable(old) || old->attrs->source == RTS_INHERIT)
|
#ifdef CONFIG_AUTO_ROUTES
|
||||||
{
|
if (a->dest == RTD_ROUTER && a->source == RTS_DEVICE)
|
||||||
DBG("krt_remove_route(ignored %I/%d)\n", net->n.prefix, net->n.pxlen);
|
return 0;
|
||||||
return;
|
#endif
|
||||||
}
|
return krt_capable(e);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
krt_add_route(rte *new)
|
krt_ioctl(int ioc, rte *e, char *name)
|
||||||
{
|
{
|
||||||
net *net = new->net;
|
net *net = e->net;
|
||||||
struct rtentry re;
|
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));
|
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_dst, net->n.prefix, 0);
|
||||||
fill_in_sockaddr((struct sockaddr_in *) &re.rt_genmask, ipa_mkmask(net->n.pxlen), 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);
|
fill_in_sockaddr((struct sockaddr_in *) &re.rt_gateway, a->gw, 0);
|
||||||
re.rt_flags |= RTF_GATEWAY;
|
re.rt_flags |= RTF_GATEWAY;
|
||||||
break;
|
break;
|
||||||
#ifndef CONFIG_AUTO_ROUTES
|
|
||||||
case RTD_DEVICE:
|
case RTD_DEVICE:
|
||||||
re.rt_dev = a->iface->name;
|
re.rt_dev = a->iface->name;
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
#ifdef RTF_REJECT
|
#ifdef RTF_REJECT
|
||||||
case RTD_UNREACHABLE:
|
case RTD_UNREACHABLE:
|
||||||
re.rt_flags |= RTF_REJECT;
|
re.rt_flags |= RTF_REJECT;
|
||||||
|
@ -97,8 +80,36 @@ krt_add_route(rte *new)
|
||||||
die("krt set: unknown flags, but not filtered");
|
die("krt set: unknown flags, but not filtered");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ioctl(if_scan_sock, SIOCADDRT, &re) < 0)
|
if (ioctl(if_scan_sock, ioc, &re) < 0)
|
||||||
log(L_ERR "SIOCADDRT(%I/%d): %m", net->n.prefix, net->n.pxlen);
|
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
|
void
|
||||||
|
@ -119,4 +130,3 @@ krt_set_preconfig(struct krt_proto *x)
|
||||||
die("krt set: missing socket");
|
die("krt set: missing socket");
|
||||||
x->p.rt_notify = krt_set_notify;
|
x->p.rt_notify = krt_set_notify;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include "lib/krt-scan.h"
|
#include "lib/krt-scan.h"
|
||||||
#include "lib/krt-set.h"
|
#include "lib/krt-set.h"
|
||||||
|
#include "lib/krt-iface.h"
|
||||||
|
|
||||||
/* Flags stored in net->n.flags */
|
/* Flags stored in net->n.flags */
|
||||||
|
|
||||||
|
@ -28,6 +29,7 @@ struct krt_proto {
|
||||||
struct proto p;
|
struct proto p;
|
||||||
struct krt_set_params setopt;
|
struct krt_set_params setopt;
|
||||||
struct krt_scan_params scanopt;
|
struct krt_scan_params scanopt;
|
||||||
|
struct krt_if_params ifopt;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct proto *cf_krt_proto;
|
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_preconfig(struct krt_proto *);
|
||||||
void krt_scan_start(struct krt_proto *);
|
void krt_scan_start(struct krt_proto *);
|
||||||
void krt_scan_shutdown(struct krt_proto *);
|
void krt_scan_shutdown(struct krt_proto *);
|
||||||
|
void krt_scan_ifaces_done(struct krt_proto *);
|
||||||
|
|
||||||
/* krt-set.c */
|
/* krt-set.c */
|
||||||
|
|
||||||
void krt_set_preconfig(struct krt_proto *);
|
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
|
#endif
|
||||||
|
|
|
@ -17,12 +17,14 @@
|
||||||
|
|
||||||
#include "nest/bird.h"
|
#include "nest/bird.h"
|
||||||
#include "nest/iface.h"
|
#include "nest/iface.h"
|
||||||
|
#include "nest/route.h"
|
||||||
|
#include "nest/protocol.h"
|
||||||
#include "lib/timer.h"
|
#include "lib/timer.h"
|
||||||
|
#include "lib/krt.h"
|
||||||
|
|
||||||
#include "unix.h"
|
#include "unix.h"
|
||||||
|
|
||||||
int if_scan_sock;
|
int if_scan_sock;
|
||||||
int if_scan_period = 60;
|
|
||||||
|
|
||||||
static timer *if_scan_timer;
|
static timer *if_scan_timer;
|
||||||
|
|
||||||
|
@ -131,8 +133,9 @@ scan_if(timer *t)
|
||||||
struct ifconf ic;
|
struct ifconf ic;
|
||||||
static int last_ifbuf_size = 4*sizeof(struct ifreq);
|
static int last_ifbuf_size = 4*sizeof(struct ifreq);
|
||||||
int res;
|
int res;
|
||||||
|
struct krt_proto *p = t->data;
|
||||||
|
|
||||||
DBG("Scanning interfaces...\n");
|
DBG("It's interface scan time...\n");
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
if (last_ifbuf_size)
|
if (last_ifbuf_size)
|
||||||
|
@ -165,6 +168,32 @@ scan_if(timer *t)
|
||||||
DBG("Increased ifconf buffer size to %d\n", last_ifbuf_size);
|
DBG("Increased ifconf buffer size to %d\n", last_ifbuf_size);
|
||||||
#endif
|
#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
|
void
|
||||||
|
@ -174,9 +203,4 @@ scan_if_init(void)
|
||||||
DBG("Using socket %d for interface and route scanning\n", if_scan_sock);
|
DBG("Using socket %d for interface and route scanning\n", if_scan_sock);
|
||||||
if (if_scan_sock < 0)
|
if (if_scan_sock < 0)
|
||||||
die("Cannot create scanning socket: %m");
|
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);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ krt_start(struct proto *P)
|
||||||
{
|
{
|
||||||
struct krt_proto *p = (struct krt_proto *) P;
|
struct krt_proto *p = (struct krt_proto *) P;
|
||||||
krt_scan_start(p);
|
krt_scan_start(p);
|
||||||
|
krt_if_start(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -37,6 +38,7 @@ krt_shutdown(struct proto *P, int time)
|
||||||
{
|
{
|
||||||
struct krt_proto *p = (struct krt_proto *) P;
|
struct krt_proto *p = (struct krt_proto *) P;
|
||||||
krt_scan_shutdown(p);
|
krt_scan_shutdown(p);
|
||||||
|
krt_if_shutdown(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -50,6 +52,7 @@ krt_preconfig(struct protocol *x)
|
||||||
p->p.shutdown = krt_shutdown;
|
p->p.shutdown = krt_shutdown;
|
||||||
krt_scan_preconfig(p);
|
krt_scan_preconfig(p);
|
||||||
krt_set_preconfig(p);
|
krt_set_preconfig(p);
|
||||||
|
krt_if_preconfig(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct protocol proto_unix_kernel = {
|
struct protocol proto_unix_kernel = {
|
||||||
|
|
Loading…
Reference in a new issue