diff options
Diffstat (limited to 'sysdep/linux')
-rw-r--r-- | sysdep/linux/Modules | 7 | ||||
-rw-r--r-- | sysdep/linux/krt-scan.c | 199 | ||||
-rw-r--r-- | sysdep/linux/krt-scan.h | 21 | ||||
-rw-r--r-- | sysdep/linux/krt-sys.h | 46 | ||||
-rw-r--r-- | sysdep/linux/netlink.Y (renamed from sysdep/linux/netlink/netlink.Y) | 2 | ||||
-rw-r--r-- | sysdep/linux/netlink.c (renamed from sysdep/linux/netlink/netlink.c) | 65 | ||||
-rw-r--r-- | sysdep/linux/netlink/Modules | 5 | ||||
-rw-r--r-- | sysdep/linux/netlink/krt-iface.h | 29 | ||||
-rw-r--r-- | sysdep/linux/netlink/krt-scan.h | 36 | ||||
-rw-r--r-- | sysdep/linux/netlink/krt-set.h | 28 | ||||
-rw-r--r-- | sysdep/linux/sysio.h | 71 |
11 files changed, 102 insertions, 407 deletions
diff --git a/sysdep/linux/Modules b/sysdep/linux/Modules index 09f4a470..940660b6 100644 --- a/sysdep/linux/Modules +++ b/sysdep/linux/Modules @@ -1,6 +1,5 @@ -#ifdef CONFIG_LINUX_SCAN -krt-scan.c -krt-scan.h -#endif +krt-sys.h +netlink.c +netlink.Y sysio.h syspriv.h diff --git a/sysdep/linux/krt-scan.c b/sysdep/linux/krt-scan.c deleted file mode 100644 index 8591607e..00000000 --- a/sysdep/linux/krt-scan.c +++ /dev/null @@ -1,199 +0,0 @@ -/* - * BIRD -- Linux Routing Table Scanning - * - * (c) 1998--2000 Martin Mares <mj@ucw.cz> - * - * Can be freely distributed and used under the terms of the GNU GPL. - */ - -#include <stdio.h> -#include <ctype.h> -#include <fcntl.h> -#include <unistd.h> -#include <net/route.h> - -#undef LOCAL_DEBUG - -#include "nest/bird.h" -#include "nest/route.h" -#include "nest/protocol.h" -#include "nest/iface.h" -#include "lib/timer.h" -#include "lib/unix.h" -#include "lib/krt.h" -#include "lib/string.h" - -static int krt_scan_fd = -1; - -struct iface * -krt_temp_iface(struct krt_proto *p, char *name) -{ - struct iface *i; - - WALK_LIST(i, p->scan.temp_ifs) - if (!strcmp(i->name, name)) - return i; - i = mb_allocz(p->p.pool, sizeof(struct iface)); - strcpy(i->name, name); - add_tail(&p->scan.temp_ifs, &i->n); - return i; -} - -static void -krt_parse_entry(byte *ent, struct krt_proto *p) -{ - u32 dest0, gw0, mask0; - ip_addr dest, gw, mask; - unsigned int flags; - int masklen; - net *net; - byte *iface = ent; - 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) - { - log(L_ERR "krt read: unable to parse `%s'", ent); - return; - } - while (*ent != '\t') - ent++; - *ent = 0; - - dest = ipa_from_u32(dest0); - ipa_ntoh(dest); - gw = ipa_from_u32(gw0); - ipa_ntoh(gw); - mask = ipa_from_u32(mask0); - ipa_ntoh(mask); - if ((masklen = ipa_mklen(mask)) < 0) - { - log(L_ERR "krt read: invalid netmask %08x", mask0); - return; - } - DBG("Got %I/%d via %I flags %x\n", dest, masklen, gw, flags); - - if (!(flags & RTF_UP)) - { - DBG("Down.\n"); - return; - } - if (flags & RTF_HOST) - masklen = 32; - if (flags & (RTF_DYNAMIC | RTF_MODIFIED)) /* Redirect route */ - { - log(L_WARN "krt: Ignoring redirect to %I/%d via %I", dest, masklen, gw); - return; - } - - net = net_get(p->p.table, dest, masklen); - - rta a = { - .proto = &p->p, - .source = RTS_INHERIT, - .scope = SCOPE_UNIVERSE, - .cast = RTC_UNICAST - }; - - if (flags & RTF_GATEWAY) - { - neighbor *ng = neigh_find(&p->p, &gw, 0); - if (ng && ng->scope) - a.iface = ng->iface; - else - { - log(L_WARN "Kernel told us to use non-neighbor %I for %I/%d", gw, net->n.prefix, net->n.pxlen); - return; - } - a.dest = RTD_ROUTER; - a.gw = gw; - } - else if (flags & RTF_REJECT) - { - a.dest = RTD_UNREACHABLE; - 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 - { - log(L_WARN "Kernel reporting unknown route type to %I/%d", net->n.prefix, net->n.pxlen); - return; - } - - e = rte_get_temp(&a); - e->net = net; - e->u.krt.src = KRT_SRC_UNKNOWN; - krt_got_route(p, e); -} - -void -krt_scan_fire(struct krt_proto *p) -{ - byte buf[32768]; - int l, seen_hdr; - - if (krt_scan_fd < 0) - { - krt_scan_fd = open("/proc/net/route", O_RDONLY); - if (krt_scan_fd < 0) - die("/proc/net/route: %m"); - } - else if (lseek(krt_scan_fd, 0, SEEK_SET) < 0) - { - log(L_ERR "krt seek: %m"); - return; - } - seen_hdr = 0; - while ((l = read(krt_scan_fd, buf, sizeof(buf))) > 0) - { - byte *z = buf; - if (l & 127) - { - log(L_ERR "krt read: misaligned entry: l=%d", l); - return; - } - while (l >= 128) - { - if (seen_hdr++) - krt_parse_entry(z, p); - z += 128; - l -= 128; - } - } - if (l < 0) - { - log(L_ERR "krt read: %m"); - return; - } - DBG("KRT scan done, seen %d lines\n", seen_hdr); -} - -void -krt_scan_construct(struct krt_config *c) -{ -} - -void -krt_scan_preconfig(struct config *c) -{ -} - -void -krt_scan_postconfig(struct krt_config *c) -{ -} - -void -krt_scan_start(struct krt_proto *x, int first) -{ - init_list(&x->scan.temp_ifs); -} - -void -krt_scan_shutdown(struct krt_proto *x, int last) -{ -} diff --git a/sysdep/linux/krt-scan.h b/sysdep/linux/krt-scan.h deleted file mode 100644 index 6c7e440f..00000000 --- a/sysdep/linux/krt-scan.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * BIRD -- Linux Kernel Route Syncer -- Scanning - * - * (c) 1998--2000 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_ - -struct krt_scan_params { -}; - -struct krt_scan_status { - list temp_ifs; /* Temporary interfaces */ -}; - -static inline int krt_scan_params_same(struct krt_scan_params *o, struct krt_scan_params *n) { return 1; } - -#endif diff --git a/sysdep/linux/krt-sys.h b/sysdep/linux/krt-sys.h new file mode 100644 index 00000000..cdee7fe3 --- /dev/null +++ b/sysdep/linux/krt-sys.h @@ -0,0 +1,46 @@ +/* + * BIRD -- Linux Kernel Netlink Route Syncer + * + * (c) 1998--2000 Martin Mares <mj@ucw.cz> + * + * Can be freely distributed and used under the terms of the GNU GPL. + */ + +#ifndef _BIRD_KRT_SYS_H_ +#define _BIRD_KRT_SYS_H_ + + +/* Kernel interfaces */ + +struct kif_params { +}; + +struct kif_status { +}; + + +static inline void kif_sys_init(struct kif_proto *p UNUSED) { } +static inline int kif_sys_reconfigure(struct kif_proto *p UNUSED, struct kif_config *n UNUSED, struct kif_config *o UNUSED) { return 1; } + +static inline void kif_sys_preconfig(struct config *c UNUSED) { } +static inline void kif_sys_postconfig(struct kif_config *c UNUSED) { } +static inline void kif_sys_init_config(struct kif_config *c UNUSED) { } +static inline void kif_sys_copy_config(struct kif_config *d UNUSED, struct kif_config *s UNUSED) { } + + +/* Kernel routes */ + +#define NL_NUM_TABLES 256 + +struct krt_params { + int table_id; /* Kernel table ID we sync with */ +}; + +struct krt_status { +}; + + +static inline void krt_sys_init(struct krt_proto *p UNUSED) { } + + +#endif diff --git a/sysdep/linux/netlink/netlink.Y b/sysdep/linux/netlink.Y index b00b0eee..51689ff9 100644 --- a/sysdep/linux/netlink/netlink.Y +++ b/sysdep/linux/netlink.Y @@ -20,7 +20,7 @@ nl_item: KERNEL TABLE expr { if ($3 <= 0 || $3 >= NL_NUM_TABLES) cf_error("Kernel routing table number out of range"); - THIS_KRT->scan.table_id = $3; + THIS_KRT->sys.table_id = $3; } ; diff --git a/sysdep/linux/netlink/netlink.c b/sysdep/linux/netlink.c index 182088a1..eaaf048e 100644 --- a/sysdep/linux/netlink/netlink.c +++ b/sysdep/linux/netlink.c @@ -548,7 +548,7 @@ nl_parse_addr(struct nlmsghdr *h) } void -krt_if_scan(struct kif_proto *p UNUSED) +kif_do_scan(struct kif_proto *p UNUSED) { struct nlmsghdr *h; @@ -634,7 +634,7 @@ nl_send_route(struct krt_proto *p, rte *e, struct ea_list *eattrs, int new) r.r.rtm_family = BIRD_AF; r.r.rtm_dst_len = net->n.pxlen; r.r.rtm_tos = 0; - r.r.rtm_table = KRT_CF->scan.table_id; + r.r.rtm_table = KRT_CF->sys.table_id; r.r.rtm_protocol = RTPROT_BIRD; r.r.rtm_scope = RT_SCOPE_UNIVERSE; nl_add_attr_ipa(&r.h, sizeof(r), RTA_DST, net->n.prefix); @@ -687,7 +687,7 @@ nl_send_route(struct krt_proto *p, rte *e, struct ea_list *eattrs, int new) } void -krt_set_notify(struct krt_proto *p, net *n, rte *new, rte *old, struct ea_list *eattrs) +krt_replace_rte(struct krt_proto *p, net *n, rte *new, rte *old, struct ea_list *eattrs) { int err = 0; @@ -940,7 +940,7 @@ nl_parse_route(struct nlmsghdr *h, int scan) } void -krt_scan_fire(struct krt_proto *p UNUSED) /* CONFIG_ALL_TABLES_AT_ONCE => p is NULL */ +krt_do_scan(struct krt_proto *p UNUSED) /* CONFIG_ALL_TABLES_AT_ONCE => p is NULL */ { struct nlmsghdr *h; @@ -1084,15 +1084,38 @@ nl_open_async(void) static u8 nl_cf_table[(NL_NUM_TABLES+7) / 8]; void -krt_scan_preconfig(struct config *c UNUSED) +krt_sys_start(struct krt_proto *p, int first) +{ + nl_table_map[KRT_CF->sys.table_id] = p; + if (first) + { + nl_open(); + nl_open_async(); + } +} + +void +krt_sys_shutdown(struct krt_proto *p UNUSED, int last UNUSED) +{ +} + +int +krt_sys_reconfigure(struct krt_proto *p UNUSED, struct krt_config *n, struct krt_config *o) +{ + return n->sys.table_id == o->sys.table_id; +} + + +void +krt_sys_preconfig(struct config *c UNUSED) { bzero(&nl_cf_table, sizeof(nl_cf_table)); } void -krt_scan_postconfig(struct krt_config *x) +krt_sys_postconfig(struct krt_config *x) { - int id = x->scan.table_id; + int id = x->sys.table_id; if (nl_cf_table[id/8] & (1 << (id%8))) cf_error("Multiple kernel syncers defined for table #%d", id); @@ -1100,35 +1123,27 @@ krt_scan_postconfig(struct krt_config *x) } void -krt_scan_construct(struct krt_config *x) +krt_sys_init_config(struct krt_config *cf) { -#ifndef IPV6 - x->scan.table_id = RT_TABLE_MAIN; -#else - x->scan.table_id = 254; -#endif + cf->sys.table_id = RT_TABLE_MAIN; } void -krt_scan_start(struct krt_proto *p, int first) +krt_sys_copy_config(struct krt_config *d, struct krt_config *s) { - init_list(&p->scan.temp_ifs); - nl_table_map[KRT_CF->scan.table_id] = p; - if (first) - { - nl_open(); - nl_open_async(); - } + d->sys.table_id = s->sys.table_id; } + + void -krt_scan_shutdown(struct krt_proto *p UNUSED, int last UNUSED) +kif_sys_start(struct kif_proto *p UNUSED) { + nl_open(); + nl_open_async(); } void -krt_if_start(struct kif_proto *p UNUSED) +kif_sys_shutdown(struct kif_proto *p UNUSED) { - nl_open(); - nl_open_async(); } diff --git a/sysdep/linux/netlink/Modules b/sysdep/linux/netlink/Modules deleted file mode 100644 index c26f7f72..00000000 --- a/sysdep/linux/netlink/Modules +++ /dev/null @@ -1,5 +0,0 @@ -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 deleted file mode 100644 index 770c6e2e..00000000 --- a/sysdep/linux/netlink/krt-iface.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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_construct(struct kif_config *c UNUSED) { }; -static inline void krt_if_shutdown(struct kif_proto *p UNUSED) { }; -static inline void krt_if_io_init(void) { }; - -static inline int kif_params_same(struct krt_if_params *old UNUSED, struct krt_if_params *new UNUSED) { return 1; } -static inline void kif_copy_params(struct krt_if_params *dest UNUSED, struct krt_if_params *src UNUSED) { } - -#endif diff --git a/sysdep/linux/netlink/krt-scan.h b/sysdep/linux/netlink/krt-scan.h deleted file mode 100644 index 9b5e075b..00000000 --- a/sysdep/linux/netlink/krt-scan.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * BIRD -- Linux Kernel Netlink Route Syncer -- Scanning - * - * (c) 1998--2000 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. - */ - -#define NL_NUM_TABLES 256 - -struct krt_scan_params { - int table_id; /* Kernel table ID we sync with */ -}; - -struct krt_scan_status { - list temp_ifs; /* Temporary interfaces */ -}; - -static inline int krt_scan_params_same(struct krt_scan_params *o, struct krt_scan_params *n) -{ - return o->table_id == n->table_id; -} - -static inline void krt_scan_copy_params(struct krt_scan_params *d UNUSED, struct krt_scan_params *s UNUSED) { } -/* table_id copied in krt_copy_config() */ - -#endif diff --git a/sysdep/linux/netlink/krt-set.h b/sysdep/linux/netlink/krt-set.h deleted file mode 100644 index 4a08217b..00000000 --- a/sysdep/linux/netlink/krt-set.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * BIRD -- Unix Kernel Netlink Route Syncer -- Dummy Include File - * - * (c) 1998--2000 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_construct(struct krt_config *c UNUSED) { }; -static inline void krt_set_start(struct krt_proto *p UNUSED, int first UNUSED) { }; -static inline void krt_set_shutdown(struct krt_proto *p UNUSED, int last UNUSED) { }; -static inline int krt_set_params_same(struct krt_set_params *o UNUSED, struct krt_set_params *n UNUSED) { return 1; } -static inline void krt_set_copy_params(struct krt_set_params *d UNUSED, struct krt_set_params *s UNUSED) { } - -#endif diff --git a/sysdep/linux/sysio.h b/sysdep/linux/sysio.h index bb522804..705a20ae 100644 --- a/sysdep/linux/sysio.h +++ b/sysdep/linux/sysio.h @@ -57,45 +57,6 @@ get_inaddr(ip_addr *a, struct in_addr *ia) ipa_ntoh(*a); } -/* - * Multicasting in Linux systems is a real mess. Not only different kernels - * have different interfaces, but also different libc's export it in different - * ways. Horrible. - */ - - -#if defined(CONFIG_LINUX_MC_MREQ) || defined(CONFIG_LINUX_MC_MREQ_BIND) -/* - * Older kernels support only struct mreq which matches interfaces by their - * addresses and thus fails on unnumbered devices. On newer 2.0 kernels - * we can use SO_BINDTODEVICE to circumvent this problem. - */ - -#define MREQ_IFA struct in_addr -#define MREQ_GRP struct ip_mreq -static inline void fill_mreq_ifa(struct in_addr *m, struct iface *ifa UNUSED, ip_addr saddr, ip_addr maddr UNUSED) -{ - set_inaddr(m, saddr); -} - -static inline void fill_mreq_grp(struct ip_mreq *m, struct iface *ifa, ip_addr saddr, ip_addr maddr) -{ - bzero(m, sizeof(*m)); -#ifdef CONFIG_LINUX_MC_MREQ_BIND - m->imr_interface.s_addr = INADDR_ANY; -#else - set_inaddr(&m->imr_interface, saddr); -#endif - set_inaddr(&m->imr_multiaddr, maddr); -} -#endif - - -#ifdef CONFIG_LINUX_MC_MREQN -/* - * 2.1 and newer kernels use struct mreqn which passes ifindex, so no - * problems with unnumbered devices. - */ #ifndef HAVE_STRUCT_IP_MREQN /* Several versions of glibc don't define this structure, so we have to do it ourselves */ @@ -107,24 +68,19 @@ struct ip_mreqn }; #endif -#define MREQ_IFA struct ip_mreqn -#define MREQ_GRP struct ip_mreqn -#define fill_mreq_ifa fill_mreq -#define fill_mreq_grp fill_mreq -static inline void fill_mreq(struct ip_mreqn *m, struct iface *ifa, ip_addr saddr, ip_addr maddr) +static inline void fill_mreqn(struct ip_mreqn *m, struct iface *ifa, ip_addr saddr, ip_addr maddr) { bzero(m, sizeof(*m)); m->imr_ifindex = ifa->index; set_inaddr(&m->imr_address, saddr); set_inaddr(&m->imr_multiaddr, maddr); } -#endif static inline char * sysio_setup_multicast(sock *s) { - MREQ_IFA m; + struct ip_mreqn m; int zero = 0; if (setsockopt(s->fd, SOL_IP, IP_MULTICAST_LOOP, &zero, sizeof(zero)) < 0) @@ -134,18 +90,15 @@ sysio_setup_multicast(sock *s) return "IP_MULTICAST_TTL"; /* This defines where should we send _outgoing_ multicasts */ - fill_mreq_ifa(&m, s->iface, s->saddr, IPA_NONE); + fill_mreqn(&m, s->iface, s->saddr, IPA_NONE); if (setsockopt(s->fd, SOL_IP, IP_MULTICAST_IF, &m, sizeof(m)) < 0) return "IP_MULTICAST_IF"; -#if defined(CONFIG_LINUX_MC_MREQ_BIND) || defined(CONFIG_LINUX_MC_MREQN) - { - struct ifreq ifr; - strcpy(ifr.ifr_name, s->iface->name); - if (setsockopt(s->fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) < 0) - return "SO_BINDTODEVICE"; - } -#endif + /* Is this necessary? */ + struct ifreq ifr; + strcpy(ifr.ifr_name, s->iface->name); + if (setsockopt(s->fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) < 0) + return "SO_BINDTODEVICE"; return NULL; } @@ -153,10 +106,10 @@ sysio_setup_multicast(sock *s) static inline char * sysio_join_group(sock *s, ip_addr maddr) { - MREQ_GRP m; + struct ip_mreqn m; /* And this one sets interface for _receiving_ multicasts from */ - fill_mreq_grp(&m, s->iface, s->saddr, maddr); + fill_mreqn(&m, s->iface, s->saddr, maddr); if (setsockopt(s->fd, SOL_IP, IP_ADD_MEMBERSHIP, &m, sizeof(m)) < 0) return "IP_ADD_MEMBERSHIP"; @@ -166,10 +119,10 @@ sysio_join_group(sock *s, ip_addr maddr) static inline char * sysio_leave_group(sock *s, ip_addr maddr) { - MREQ_GRP m; + struct ip_mreqn m; /* And this one sets interface for _receiving_ multicasts from */ - fill_mreq_grp(&m, s->iface, s->saddr, maddr); + fill_mreqn(&m, s->iface, s->saddr, maddr); if (setsockopt(s->fd, SOL_IP, IP_DROP_MEMBERSHIP, &m, sizeof(m)) < 0) return "IP_DROP_MEMBERSHIP"; |