summaryrefslogtreecommitdiff
path: root/sysdep/linux
diff options
context:
space:
mode:
authorOndrej Filip <feela@network.cz>2012-05-11 00:01:29 +0200
committerOndrej Filip <feela@network.cz>2012-05-11 00:01:29 +0200
commit72b2db8db7534c52e928618410ec1f18787752c8 (patch)
tree7eee7f4c26a36f72e0700e9e5d78056f5329f85c /sysdep/linux
parent2795700c3158fa52b6cf957e9d0b9ad4a27c67a5 (diff)
parent95616c820248018f4999972cad315f2da60e4960 (diff)
Merge branch 'master' of ssh://git.nic.cz/bird
Diffstat (limited to 'sysdep/linux')
-rw-r--r--sysdep/linux/Modules7
-rw-r--r--sysdep/linux/krt-scan.c199
-rw-r--r--sysdep/linux/krt-scan.h21
-rw-r--r--sysdep/linux/krt-sys.h46
-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/Modules5
-rw-r--r--sysdep/linux/netlink/krt-iface.h29
-rw-r--r--sysdep/linux/netlink/krt-scan.h36
-rw-r--r--sysdep/linux/netlink/krt-set.h28
-rw-r--r--sysdep/linux/sysio.h71
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";