diff options
Diffstat (limited to 'sysdep/linux')
-rw-r--r-- | sysdep/linux/Modules | 3 | ||||
-rw-r--r-- | sysdep/linux/krt-scan.Y | 33 | ||||
-rw-r--r-- | sysdep/linux/krt-scan.c | 188 | ||||
-rw-r--r-- | sysdep/linux/krt-scan.h | 5 | ||||
-rw-r--r-- | sysdep/linux/netlink/Modules | 8 | ||||
-rw-r--r-- | sysdep/linux/netlink/krt-iface.h | 26 | ||||
-rw-r--r-- | sysdep/linux/netlink/krt-scan.h | 26 | ||||
-rw-r--r-- | sysdep/linux/netlink/krt-set.h | 26 | ||||
-rw-r--r-- | sysdep/linux/netlink/krt.Y | 46 | ||||
-rw-r--r-- | sysdep/linux/netlink/krt.h | 30 | ||||
-rw-r--r-- | sysdep/linux/netlink/netlink.Y | 25 | ||||
-rw-r--r-- | sysdep/linux/netlink/netlink.c (renamed from sysdep/linux/netlink/krt.c) | 113 |
12 files changed, 180 insertions, 349 deletions
diff --git a/sysdep/linux/Modules b/sysdep/linux/Modules index 03d032d..4a99916 100644 --- a/sysdep/linux/Modules +++ b/sysdep/linux/Modules @@ -1,5 +1,4 @@ -#ifndef CONFIG_NETLINK +#ifdef CONFIG_LINUX_SCAN krt-scan.c krt-scan.h -krt-scan.Y #endif diff --git a/sysdep/linux/krt-scan.Y b/sysdep/linux/krt-scan.Y deleted file mode 100644 index 5833989..0000000 --- a/sysdep/linux/krt-scan.Y +++ /dev/null @@ -1,33 +0,0 @@ -/* - * BIRD -- Linux Kernel 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_scan_item ';') - -krt_scan_item: - LEARN bool { - ((struct krt_config *) this_proto)->scanopt.learn = $2; - } - | ROUTE SCAN TIME expr { - /* Scan time of 0 means scan on startup only */ - ((struct krt_config *) this_proto)->scanopt.scan_time = $4; - } - ; - -CF_CODE - -CF_END diff --git a/sysdep/linux/krt-scan.c b/sysdep/linux/krt-scan.c index 1428a7a..3e5a240 100644 --- a/sysdep/linux/krt-scan.c +++ b/sysdep/linux/krt-scan.c @@ -23,60 +23,34 @@ #include "lib/unix.h" #include "lib/krt.h" -#define SCANOPT struct krt_scan_params *p = &(((struct krt_config *)(x->p.cf))->scanopt) -#define SCANSTAT struct krt_scan_status *s = &x->scanstat - static int krt_scan_fd = -1; -/* FIXME: Filtering */ - struct iface * -krt_temp_iface(struct krt_proto *x, char *name) +krt_temp_iface(struct krt_proto *p, char *name) { - SCANOPT; - SCANSTAT; struct iface *i; - WALK_LIST(i, s->temp_ifs) + WALK_LIST(i, p->scan.temp_ifs) if (!strcmp(i->name, name)) return i; - i = mb_alloc(x->p.pool, sizeof(struct iface)); + i = mb_alloc(p->p.pool, sizeof(struct iface)); bzero(i, sizeof(*i)); strcpy(i->name, name); - add_tail(&s->temp_ifs, &i->n); + add_tail(&p->scan.temp_ifs, &i->n); return i; } -static int -krt_uptodate(rte *k, rte *e) -{ - rta *ka = k->attrs, *ea = e->attrs; - - if (ka->dest != ea->dest) - return 0; - switch (ka->dest) - { - case RTD_ROUTER: - return ipa_equal(ka->gw, ea->gw); - case RTD_DEVICE: - return !strcmp(ka->iface->name, ea->iface->name); - default: - return 1; - } -} - static void -krt_parse_entry(byte *ent, struct krt_proto *x) +krt_parse_entry(byte *ent, struct krt_proto *p) { - SCANOPT; u32 dest0, gw0, mask0; ip_addr dest, gw, mask; - unsigned int flags, verdict; + unsigned int flags; int masklen; net *net; byte *iface = ent; rta a; - rte *e, *old; + rte *e; if (sscanf(ent, "%*s\t%x\t%x\t%x\t%*d\t%*d\t%*d\t%x\t", &dest0, &gw0, &flags, &mask0) != 4) { @@ -114,14 +88,8 @@ krt_parse_entry(byte *ent, struct krt_proto *x) } 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 = &x->p; + a.proto = &p->p; a.source = RTS_INHERIT; a.scope = SCOPE_UNIVERSE; a.cast = RTC_UNICAST; @@ -132,7 +100,7 @@ krt_parse_entry(byte *ent, struct krt_proto *x) if (flags & RTF_GATEWAY) { - neighbor *ng = neigh_find(&x->p, &gw, 0); + neighbor *ng = neigh_find(&p->p, &gw, 0); if (ng) a.iface = ng->iface; else @@ -150,7 +118,7 @@ krt_parse_entry(byte *ent, struct krt_proto *x) { a.dest = RTD_DEVICE; a.gw = IPA_NONE; - a.iface = krt_temp_iface(x, iface); + a.iface = krt_temp_iface(p, iface); } else { @@ -160,43 +128,15 @@ krt_parse_entry(byte *ent, struct krt_proto *x) e = rte_get_temp(&a); e->net = net; - old = net->routes; - if (old && !krt_capable(old)) - old = NULL; - if (old) - { - if (krt_uptodate(e, net->routes)) - verdict = KRF_SEEN; - else - verdict = KRF_UPDATE; - } - else if (p->learn && !net->routes) - verdict = KRF_LEARN; - else - verdict = KRF_DELETE; - - DBG("krt_parse_entry: verdict=%s\n", ((char *[]) { "CREATE", "SEEN", "UPDATE", "DELETE", "LEARN" }) [verdict]); - - net->n.flags = verdict; - if (verdict != KRF_SEEN) - { - /* Get a cached copy of attributes and link the route */ - a.source = RTS_DUMMY; - e->attrs = rta_lookup(&a); - e->next = net->routes; - net->routes = e; - } - else - rte_free(e); + krt_got_route(p, e); } -static int -krt_scan_proc(struct krt_proto *p) +void +krt_scan_fire(struct krt_proto *p) { byte buf[32768]; int l, seen_hdr; - DBG("Scanning kernel routing table...\n"); if (krt_scan_fd < 0) { krt_scan_fd = open("/proc/net/route", O_RDONLY); @@ -206,7 +146,7 @@ krt_scan_proc(struct krt_proto *p) else if (lseek(krt_scan_fd, 0, SEEK_SET) < 0) { log(L_ERR "krt seek: %m"); - return 0; + return; } seen_hdr = 0; while ((l = read(krt_scan_fd, buf, sizeof(buf))) > 0) @@ -215,7 +155,7 @@ krt_scan_proc(struct krt_proto *p) if (l & 127) { log(L_ERR "krt read: misaligned entry: l=%d", l); - return 0; + return; } while (l >= 128) { @@ -228,114 +168,20 @@ krt_scan_proc(struct krt_proto *p) if (l < 0) { log(L_ERR "krt read: %m"); - return 0; + return; } DBG("KRT scan done, seen %d lines\n", seen_hdr); - return 1; -} - -static void -krt_prune(struct krt_proto *p) -{ - struct rtable *t = &master_table; - struct fib_node *f; - - DBG("Pruning routes...\n"); - while (t && t->tos) - t = t->sibling; - if (!t) - return; - FIB_WALK(&t->fib, f) - { - net *n = (net *) f; - int verdict = f->flags; - rte *new, *old; - - if (verdict != KRF_CREATE && verdict != KRF_SEEN) - { - old = n->routes; - n->routes = old->next; - } - else - old = NULL; - new = n->routes; - - switch (verdict) - { - case KRF_CREATE: - if (new) - { - if (new->attrs->source == RTS_INHERIT) - { - DBG("krt_prune: removing inherited %I/%d\n", n->n.prefix, n->n.pxlen); - rte_update(n, &p->p, NULL); - } - else - { - DBG("krt_prune: reinstalling %I/%d\n", n->n.prefix, n->n.pxlen); - krt_add_route(new); - } - } - break; - case KRF_SEEN: - /* Nothing happens */ - break; - case KRF_UPDATE: - DBG("krt_prune: updating %I/%d\n", n->n.prefix, n->n.pxlen); - krt_remove_route(old); - krt_add_route(new); - break; - case KRF_DELETE: - DBG("krt_prune: deleting %I/%d\n", n->n.prefix, n->n.pxlen); - krt_remove_route(old); - break; - case KRF_LEARN: - DBG("krt_prune: learning %I/%d\n", n->n.prefix, n->n.pxlen); - rte_update(n, &p->p, new); - break; - default: - bug("krt_prune: invalid route status"); - } - - if (old) - rte_free(old); - f->flags = 0; - } - FIB_WALK_END; -} - -void -krt_scan_ifaces_done(struct krt_proto *x) -{ - SCANOPT; - SCANSTAT; - - s->accum_time += ((struct krt_config *) x->p.cf)->ifopt.scan_time; - if (p->scan_time && s->accum_time >= p->scan_time) - { - s->accum_time %= p->scan_time; - if (krt_scan_proc(x)) - krt_prune(x); - } } void krt_scan_preconfig(struct krt_config *c) { - c->scanopt.scan_time = 60; - c->scanopt.learn = 0; } void krt_scan_start(struct krt_proto *x) { - SCANOPT; - SCANSTAT; - - /* Force krt scan after first interface scan */ - s->accum_time = p->scan_time - ((struct krt_config *) x->p.cf)->ifopt.scan_time; - - init_list(&s->temp_ifs); + init_list(&x->scan.temp_ifs); } void diff --git a/sysdep/linux/krt-scan.h b/sysdep/linux/krt-scan.h index ef1f729..c5bf588 100644 --- a/sysdep/linux/krt-scan.h +++ b/sysdep/linux/krt-scan.h @@ -1,5 +1,5 @@ /* - * BIRD -- Linux Kernel Route Syncer -- Scanning Parameters + * BIRD -- Linux Kernel Route Syncer -- Scanning * * (c) 1998--1999 Martin Mares <mj@ucw.cz> * @@ -10,13 +10,10 @@ #define _BIRD_KRT_SCAN_H_ struct krt_scan_params { - int learn; /* Should we learn routes from the kernel? */ - int scan_time; /* How often should we scan krt, 0=only on startup */ }; struct krt_scan_status { list temp_ifs; /* Temporary interfaces */ - int accum_time; /* Accumulated scanning time */ }; #endif diff --git a/sysdep/linux/netlink/Modules b/sysdep/linux/netlink/Modules index 8033810..c26f7f7 100644 --- a/sysdep/linux/netlink/Modules +++ b/sysdep/linux/netlink/Modules @@ -1,3 +1,5 @@ -krt.c -krt.h -krt.Y +krt-iface.h +krt-set.h +krt-scan.h +netlink.c +netlink.Y diff --git a/sysdep/linux/netlink/krt-iface.h b/sysdep/linux/netlink/krt-iface.h new file mode 100644 index 0000000..5dfb934 --- /dev/null +++ b/sysdep/linux/netlink/krt-iface.h @@ -0,0 +1,26 @@ +/* + * BIRD -- Unix Kernel Netlink Interface Syncer -- Dummy Include File + * + * (c) 1998--1999 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_ + +/* + * We don't have split iface/scan/set parts. See krt-scan.h. + */ + +struct krt_if_params { +}; + +struct krt_if_status { +}; + +static inline void krt_if_preconfig(struct krt_config *c) { }; +static inline void krt_if_start(struct krt_proto *p) { }; +static inline void krt_if_shutdown(struct krt_proto *p) { }; + +#endif diff --git a/sysdep/linux/netlink/krt-scan.h b/sysdep/linux/netlink/krt-scan.h new file mode 100644 index 0000000..cd118de --- /dev/null +++ b/sysdep/linux/netlink/krt-scan.h @@ -0,0 +1,26 @@ +/* + * BIRD -- Linux Kernel Netlink Route Syncer -- Scanning + * + * (c) 1998--1999 Martin Mares <mj@ucw.cz> + * + * Can be freely distributed and used under the terms of the GNU GPL. + */ + +#ifndef _BIRD_KRT_SCAN_H_ +#define _BIRD_KRT_SCAN_H_ + +/* + * We don't have split iface/scan/set for Netlink. All options + * and run-time parameters are declared here instead of splitting + * to krt-set.h, krt-iface.h and this file. + */ + +struct krt_scan_params { + int async; /* Allow asynchronous events */ +}; + +struct krt_scan_status { + list temp_ifs; /* Temporary interfaces */ +}; + +#endif diff --git a/sysdep/linux/netlink/krt-set.h b/sysdep/linux/netlink/krt-set.h new file mode 100644 index 0000000..32fdad0 --- /dev/null +++ b/sysdep/linux/netlink/krt-set.h @@ -0,0 +1,26 @@ +/* + * BIRD -- Unix Kernel Netlink Route Syncer -- Dummy Include File + * + * (c) 1998--1999 Martin Mares <mj@ucw.cz> + * + * Can be freely distributed and used under the terms of the GNU GPL. + */ + +#ifndef _BIRD_KRT_SET_H_ +#define _BIRD_KRT_SET_H_ + +/* + * We don't have split iface/scan/set parts. See krt-scan.h. + */ + +struct krt_set_params { +}; + +struct krt_set_status { +}; + +static inline void krt_set_preconfig(struct krt_config *c) { }; +static inline void krt_set_start(struct krt_proto *p) { }; +static inline void krt_set_shutdown(struct krt_proto *p) { }; + +#endif diff --git a/sysdep/linux/netlink/krt.Y b/sysdep/linux/netlink/krt.Y deleted file mode 100644 index c572640..0000000 --- a/sysdep/linux/netlink/krt.Y +++ /dev/null @@ -1,46 +0,0 @@ -/* - * BIRD -- Netlink Interface Configuration - * - * (c) 1999 Martin Mares <mj@ucw.cz> - * - * Can be freely distributed and used under the terms of the GNU GPL. - */ - -CF_HDR - -#include "lib/krt.h" - -#define KRT_PROTO ((struct krt_config *) this_proto) - -CF_DECLS - -CF_KEYWORDS(KERNEL, PERSIST, ROUTE, SCAN, TIME, LEARN) - -CF_GRAMMAR - -/* Kernel protocol */ - -CF_ADDTO(proto, kern_proto '}') - -kern_proto_start: proto_start KERNEL { - if (!(this_proto = cf_krt)) cf_error("Kernel protocol already defined"); - cf_krt = NULL; - } - ; - -kern_proto: - kern_proto_start '{' - | kern_proto proto_item ';' - | kern_proto kern_item ';' - ; - -kern_item: - PERSIST bool { KRT_PROTO->persist = $2; } - | SCAN TIME expr { KRT_PROTO->scan_time = $3; } - | LEARN bool { KRT_PROTO->learn = $2; } - | ROUTE SCAN TIME expr { KRT_PROTO->route_scan_time = $4; } - ; - -CF_CODE - -CF_END diff --git a/sysdep/linux/netlink/krt.h b/sysdep/linux/netlink/krt.h deleted file mode 100644 index 8dd55cc..0000000 --- a/sysdep/linux/netlink/krt.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * BIRD -- Linux Netlink Interface - * - * (c) 1999 Martin Mares <mj@ucw.cz> - * - * Can be freely distributed and used under the terms of the GNU GPL. - */ - -#ifndef _BIRD_NETLINK_KRT_H_ -#define _BIRD_NETLINK_KRT_H_ - -extern struct protocol proto_unix_kernel; - -struct krt_config { - struct proto_config c; - int persist; /* Keep routes when we exit */ - int scan_time; /* How often we re-scan interfaces */ - int route_scan_time; /* How often we re-scan routes */ - int learn; /* Learn routes from other sources */ -}; - -extern struct proto_config *cf_krt; - -struct krt_proto { - struct proto p; -}; - -void scan_if_init(void); - -#endif diff --git a/sysdep/linux/netlink/netlink.Y b/sysdep/linux/netlink/netlink.Y new file mode 100644 index 0000000..b5c45f2 --- /dev/null +++ b/sysdep/linux/netlink/netlink.Y @@ -0,0 +1,25 @@ +/* + * BIRD -- Linux Netlink Configuration + * + * (c) 1999 Martin Mares <mj@ucw.cz> + * + * Can be freely distributed and used under the terms of the GNU GPL. + */ + +CF_HDR + +CF_DECLS + +CF_KEYWORDS(ASYNC) + +CF_GRAMMAR + +CF_ADDTO(kern_proto, kern_proto nl_item ';') + +nl_item: + ASYNC bool { THIS_KRT->scan.async = $2; } + ; + +CF_CODE + +CF_END diff --git a/sysdep/linux/netlink/krt.c b/sysdep/linux/netlink/netlink.c index c399e20..6e6fafd 100644 --- a/sysdep/linux/netlink/krt.c +++ b/sysdep/linux/netlink/netlink.c @@ -15,8 +15,6 @@ #define LOCAL_DEBUG -#undef ASYNC_NETLINK /* Define if async notifications should be used (debug) */ - #include "nest/bird.h" #include "nest/route.h" #include "nest/protocol.h" @@ -46,13 +44,11 @@ #define MSG_TRUNC 0x20 #endif -struct proto_config *cf_krt; - /* * Synchronous Netlink interface */ -static int nl_sync_fd; /* Unix socket for synchronous netlink actions */ +static int nl_sync_fd = -1; /* Unix socket for synchronous netlink actions */ static u32 nl_sync_seq; /* Sequence number of last request sent */ static byte *nl_rx_buffer; /* Receive buffer */ @@ -62,6 +58,19 @@ static struct nlmsghdr *nl_last_hdr; /* Recently received packet */ static unsigned int nl_last_size; static void +nl_open(void) +{ + if (nl_sync_fd < 0) + { + nl_sync_fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); + if (nl_sync_fd < 0) + die("Unable to open rtnetlink socket: %m"); + nl_sync_seq = now; + nl_rx_buffer = xmalloc(nl_rx_size); + } +} + +static void nl_send(void *rq, int size) { struct nlmsghdr *nh = rq; @@ -327,8 +336,8 @@ nl_parse_addr(struct nlmsghdr *h) if_update(&f); } -static void -nl_scan_ifaces(void) +void +krt_if_scan(struct krt_proto *p) { struct nlmsghdr *h; @@ -352,46 +361,48 @@ nl_scan_ifaces(void) } /* - * Asynchronous Netlink interface + * Routes */ -static sock *nl_async_sk; /* BIRD socket for asynchronous notifications */ +int +krt_capable(rte *e) +{ + return 1; /* FIXME */ +} -static int -nl_async_hook(sock *sk, int size) +void +krt_set_notify(struct proto *p, net *n, rte *new, rte *old) +{ + /* FIXME */ +} + +void +krt_scan_fire(struct krt_proto *p) { - DBG("nl_async_hook\n"); - return 0; } /* - * Protocol core + * Asynchronous Netlink interface */ -static void -krt_preconfig(struct protocol *x, struct config *c) -{ - struct krt_config *z = proto_config_new(&proto_unix_kernel, sizeof(struct krt_config)); - - cf_krt = &z->c; - z->c.preference = DEF_PREF_UKR; -} +static sock *nl_async_sk; /* BIRD socket for asynchronous notifications */ -static struct proto * -krt_init(struct proto_config *c) +static int +nl_async_hook(sock *sk, int size) { - struct krt_proto *p = proto_new(c, sizeof(struct krt_proto)); - - return &p->p; + DBG("nl_async_hook\n"); + return 0; } static void -nl_open_async(struct proto *p) +nl_open_async(struct krt_proto *p) { sock *sk; struct sockaddr_nl sa; - sk = nl_async_sk = sk_new(p->pool); + DBG("KRT: Opening async netlink socket\n"); + + sk = nl_async_sk = sk_new(p->p.pool); sk->type = SK_MAGIC; sk->rx_hook = nl_async_hook; sk->fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); @@ -405,43 +416,25 @@ nl_open_async(struct proto *p) die("Unable to bind secondary rtnetlink socket: %m"); } -static int -krt_start(struct proto *p) -{ -#ifdef ASYNC_NETLINK - nl_open_async(p); -#endif - - /* FIXME: Filter kernel routing table etc. */ +/* + * Interface to the UNIX krt module + */ - return PS_UP; +void +krt_scan_preconfig(struct krt_config *x) +{ + x->scan.async = 1; } -static int -krt_shutdown(struct proto *p) +void +krt_scan_start(struct krt_proto *p) { - /* FIXME: Remove all our routes from the kernel */ - - return PS_DOWN; + nl_open(); + if (KRT_CF->scan.async) + nl_open_async(p); } void -scan_if_init(void) +krt_scan_shutdown(struct krt_proto *p) { - nl_sync_fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); - if (nl_sync_fd < 0) - die("Unable to open rtnetlink socket: %m"); - nl_sync_seq = now; - nl_rx_buffer = xmalloc(nl_rx_size); - /* FIXME: Should we fetch our local address and compare it with addresses of all incoming messages? */ - - nl_scan_ifaces(); } - -struct protocol proto_unix_kernel = { - name: "Kernel", - preconfig: krt_preconfig, - init: krt_init, - start: krt_start, - shutdown: krt_shutdown -}; |