1
0
mirror of https://gitlab.labs.nic.cz/labs/bird.git synced 2024-05-11 16:54:54 +00:00

Cleanup in sysdep KRT code, part 2.

Remove support for historic Linux kernels,
merge krt-iface, krt-set and krt-scan stub headers.
This commit is contained in:
Ondrej Zajicek
2012-04-30 22:21:52 +02:00
parent 396dfa9042
commit f1aceff59b
33 changed files with 38 additions and 2224 deletions

View File

@@ -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

View File

@@ -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)
{
}

View File

@@ -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

View File

@@ -1,5 +0,0 @@
krt-iface.h
krt-set.h
krt-scan.h
netlink.c
netlink.Y

View File

@@ -1,33 +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 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) { }
static inline void kif_sys_io_init(void) { }
#endif

View File

@@ -1,30 +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_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

View File

@@ -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

View File

@@ -1,32 +0,0 @@
/*
* BIRD -- Linux Netlink Configuration
*
* (c) 1999--2000 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, KERNEL, TABLE, KRT_PREFSRC, KRT_REALM)
CF_GRAMMAR
CF_ADDTO(kern_proto, kern_proto nl_item ';')
nl_item:
KERNEL TABLE expr {
if ($3 <= 0 || $3 >= NL_NUM_TABLES)
cf_error("Kernel routing table number out of range");
THIS_KRT->sys.table_id = $3;
}
;
CF_ADDTO(dynamic_attr, KRT_PREFSRC { $$ = f_new_dynamic_attr(EAF_TYPE_IP_ADDRESS, T_IP, EA_KRT_PREFSRC); })
CF_ADDTO(dynamic_attr, KRT_REALM { $$ = f_new_dynamic_attr(EAF_TYPE_INT, T_INT, EA_KRT_REALM); })
CF_CODE
CF_END

View File

File diff suppressed because it is too large Load Diff

View File

@@ -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";