summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile23
-rw-r--r--Rules12
-rw-r--r--TODO143
-rw-r--r--lib/Makefile3
-rw-r--r--lib/birdlib.h17
-rw-r--r--lib/lists.c76
-rw-r--r--lib/lists.h42
-rw-r--r--lib/resource.h70
-rw-r--r--lib/socket.h16
-rw-r--r--lib/timer.h26
-rw-r--r--lib/unaligned.h12
-rw-r--r--nest/Makefile3
-rw-r--r--nest/bird.h24
-rw-r--r--nest/confile.h12
-rw-r--r--nest/iface.h12
-rw-r--r--nest/ipv4.h20
-rw-r--r--nest/ipv6.h21
-rw-r--r--nest/main.c23
-rw-r--r--nest/protocol.h66
-rw-r--r--nest/route.h190
-rw-r--r--sysdep/cf/linux-20.h11
-rw-r--r--sysdep/cf/linux-21.h11
-rw-r--r--sysdep/cf/linux-v6.h13
-rw-r--r--sysdep/config.h50
-rw-r--r--sysdep/linux/Makefile1
25 files changed, 897 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 00000000..0c62fe54
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,23 @@
+# Makefile for the BIRD Internet Routing Daemon
+# (c) 1998 Martin Mares <mj@ucw.cz>
+
+TOPDIR=$(shell pwd)
+CFLAGS=-O2 -Wall -W -Wstrict-prototypes -Wno-unused -Wno-parentheses -I$(TOPDIR)
+
+PROTOCOLS=
+DIRS=sysdep/linux nest $(protocols) lib
+ARCHS=$(join $(addsuffix /,$(DIRS)),$(subst /,_,$(addsuffix .a,$(DIRS))))
+
+export
+
+all: all-dirs bird
+
+all-dirs:
+ set -e ; for a in $(DIRS) ; do $(MAKE) -C $$a ; done
+
+bird: $(ARCHS)
+ $(CC) $(LDFLAGS) -o $@ $^
+
+clean:
+ rm -f `find . -name "*~" -or -name "*.[oa]" -or -name "\#*\#" -or -name TAGS -or -name core`
+ rm -f bird
diff --git a/Rules b/Rules
new file mode 100644
index 00000000..f6baacdb
--- /dev/null
+++ b/Rules
@@ -0,0 +1,12 @@
+# Makefile for the BIRD Internet Routing Daemon
+# (c) 1998 Martin Mares <mj@ucw.cz>
+
+THISDIR=$(shell pwd)
+RELDIR=$(subst $(TOPDIR)/,,$(THISDIR))
+ANAME=$(subst /,_,$(RELDIR)).a
+
+all: $(ANAME)
+
+$(ANAME): $(OBJS)
+ rm -f $(ANAME)
+ ar rcs $(ANAME) $(OBJS)
diff --git a/TODO b/TODO
new file mode 100644
index 00000000..10aeef91
--- /dev/null
+++ b/TODO
@@ -0,0 +1,143 @@
+Core
+~~~~
+- route validation
+- fake multipath?
+- config file: symbolic constants?
+- counters (according to SNMP MIB?)
+- generation of subnet mask ICMP's for v6?
+- debugging dumps and protocol tracing!
+- unaligned accesses?
+
+
+RIP
+~~~
+- RIP: export-only and import-only mode?
+- drop RIPv1 (Historic protocol)?
+
+OSPF
+~~~~
+
+Almquist & Kastenholz [Page 111]
+RFC 1716 Towards Requirements for IP Routers November 1994
+
+
+7.2.2.2 Specific Issues
+
+ Virtual Links
+
+ There is a minor error in the specification that can cause
+ routing loops when all of the following conditions are
+ simultaneously true:
+
+ (1) A virtual link is configured through a transit area,
+
+ (2) Two separate paths exist, each having the same
+ endpoints, but one utilizing only non-virtual
+ backbone links, and the other using links in the
+ transit area, and
+
+ (3) The latter path is part of the (underlying physical
+ representation of the) configured virtual link,
+ routing loops may occur.
+
+ To prevent this, an implementation of OSPF SHOULD invoke
+ the calculation in Section 16.3 of [ROUTE:1] whenever any
+ part of the path to the destination is a virtual link (the
+ specification only says this is necessary when the first
+ hop is a virtual link).
+
+BGP
+~~~
+- BGP:
+ - in, local, out RIB
+ - maxsize=4096
+ - BGP identifier aka router id
+ - removal of loops
+ - aggregation, ATOMIC_AGGREGATE
+ - communities
+ - confederations
+ - attributes must be sorted!
+ - re-export of NEXT_HOP attribute
+ - BGP session over currently down interface
+ - route flap dampening?
+ - LOCAL_PREF attribute
+ - error notification received -> log error
+ - set TTL to 1 (configurable?)
+ - consulting IGP for next-hop information? (what if it changes?)
+ - inter-advertisement delay???!
+ - normalize (sort) incoming AS-SET's
+ - maximum length of AS paths
+
+ - expected neighbor AS
+ - hold time
+ - idle timer after error: initial value, exponential growth, maximum value
+
+- address testing macros (ALL_ZEROS)
+- all internal tables are in network order (?)
+- logging of errors and debug dumps
+- filter: logging of dropped routes (?)
+- limitation of memory consumption: per-process and total
+- alloca
+- precedence of all packets (incl. TCP)
+- adding of route: clear all bits not covered by masklen
+- switch: generate default route only if at least one BGP connection exists
+
+- route update: new, change, remove
+- route recalculation timing
+
+- CONFIG_TOS
+- CONFIG_MULTIPATH
+
+- reconfiguration without restart of all protocols?
+- change of interface address: ??? (down and up?)
+- "generate default route" switch for all IGP's
+
+- RIPv2:
+ - Route Tag
+ - limit routing table xfer (frequency, only to neighbors)
+ - multicast on/off
+ - remember routes for all neighbors?
+
+- BGP:
+ - import of IGP routes (use external route tags from OSPF)
+
+- Interface:
+ - RIP metric
+ - multicast capability flag
+ - MTU
+ - OSPF metrics (per-TOS)
+
+- running protocol on an interface:
+ - interface is not required to exist
+ - can specify a wildcard pattern or an interface list
+
+- preferences:
+ - directly connected
+ - static
+ - OSPF internal, OSPF ext type 1 (comparable metrics), OSPF inter-area
+ - RIP
+ - BGP
+ - OSPF ext type 2
+ - sink
+
+- lib:
+ - MD5
+
+- OSPF:
+ - Dijkstra: use Fibonacci heaps?
+ - point-to-point interface with address: advertise as stub network
+ - static routes: stub networks?
+ - modes: PtP, PtP-unnumbered, Broadcast, NBMA, point-to-multipoint
+ - importing of device routes for networks where we don't run OSPF
+ - tie breaking for equal type 2 ext metrics by using internal (type 1) metric
+ - SPF tree recalc timing (per-area timers?)
+ - aggregation: specify network list for each area
+ - stub area: either no external routes or only default route
+ - automatic generation of external route tags (RFC1403) -- what about
+ using the same rule for RIPv2? [shared code?]
+
+- timers - one-shot and periodic, resolution 1 sec, randomized
+- re-configuration: restart of routing protocols (shutdown mode)
+- route: originating AS
+
+- Check incoming packets and log errors!!
diff --git a/lib/Makefile b/lib/Makefile
new file mode 100644
index 00000000..214f76af
--- /dev/null
+++ b/lib/Makefile
@@ -0,0 +1,3 @@
+OBJS=lists.o
+
+include $(TOPDIR)/Rules
diff --git a/lib/birdlib.h b/lib/birdlib.h
new file mode 100644
index 00000000..fb4814f9
--- /dev/null
+++ b/lib/birdlib.h
@@ -0,0 +1,17 @@
+/*
+ * BIRD Library
+ *
+ * (c) 1998 Martin Mares <mj@ucw.cz>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#ifndef _BIRD_BIRDLIB_H_
+#define _BIRD_BIRDLIB_H_
+
+/* Ugly structure offset handling macros */
+
+#define OFFSETOF(s, i) ((unsigned int)&((s *)0)->i)
+#define SKIP_BACK(s, i, p) ((s *)((char *)p - OFFSETOF(s, i)))
+
+#endif
diff --git a/lib/lists.c b/lib/lists.c
new file mode 100644
index 00000000..321a5f05
--- /dev/null
+++ b/lib/lists.c
@@ -0,0 +1,76 @@
+/*
+ * BIRD Library -- Linked Lists
+ *
+ * (c) 1998 Martin Mares <mj@ucw.cz>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#define _BIRD_LISTS_C_
+
+#include <nest/bird.h>
+#include <lib/lists.h>
+
+LIST_INLINE void
+add_tail(list *l, node *n)
+{
+ node *z = l->tail;
+
+ n->next = (node *) &l->tail;
+ n->prev = z;
+ z->next = n;
+ l->tail = n;
+}
+
+LIST_INLINE void
+add_head(list *l, node *n)
+{
+ node *z = l->head;
+
+ n->next = z;
+ n->prev = (node *) &l->head;
+ z->prev = n;
+ l->head = n;
+}
+
+LIST_INLINE void
+insert_node(node *n, node *after)
+{
+ node *z = after->next;
+
+ n->next = z;
+ n->prev = after;
+ after->next = n;
+ z->prev = n;
+}
+
+LIST_INLINE void
+rem_node(node *n)
+{
+ node *z = n->prev;
+ node *x = n->next;
+
+ z->next = x;
+ x->prev = z;
+}
+
+LIST_INLINE void
+init_list(list *l)
+{
+ l->head = (node *) &l->null;
+ l->null = NULL;
+ l->tail = (node *) &l->head;
+}
+
+LIST_INLINE void
+add_tail_list(list *to, list *l)
+{
+ node *p = to->tail;
+ node *q = l->head;
+
+ p->next = q;
+ q->prev = p;
+ q = l->tail;
+ q->next = (node *) &to->null;
+ to->tail = q;
+}
diff --git a/lib/lists.h b/lib/lists.h
new file mode 100644
index 00000000..acc054d8
--- /dev/null
+++ b/lib/lists.h
@@ -0,0 +1,42 @@
+/*
+ * BIRD Library -- Linked Lists
+ *
+ * (c) 1998 Martin Mares <mj@ucw.cz>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#ifndef _BIRD_LISTS_H_
+#define _BIRD_LISTS_H_
+
+typedef struct node {
+ struct node *next, *prev;
+} node;
+
+typedef struct list { /* In fact two overlayed nodes */
+ struct node *head, *null, *tail;
+} list;
+
+#define NODE (node *)
+#define HEAD(list) ((void *)((list).head))
+#define TAIL(list) ((void *)((list).tail))
+#define WALK_LIST(n,list) for((n)=HEAD(list);(NODE (n))->next; \
+ n=(void *)((NODE (n))->next))
+#define EMPTY_LIST(list) (!(list).head->next)
+
+void add_tail(list *, node *);
+void add_head(list *, node *);
+void rem_node(node *);
+void add_tail_list(list *, list *);
+void init_list(list *);
+void insert_node(node *, node *);
+
+#ifndef _BIRD_LISTS_C_
+#define LIST_INLINE extern inline
+#include <lib/lists.c>
+#undef LIST_INLINE
+#else
+#define LIST_INLINE
+#endif
+
+#endif
diff --git a/lib/resource.h b/lib/resource.h
new file mode 100644
index 00000000..a1d229ec
--- /dev/null
+++ b/lib/resource.h
@@ -0,0 +1,70 @@
+/*
+ * BIRD Resource Manager
+ *
+ * (c) 1998 Martin Mares <mj@ucw.cz>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#ifndef _BIRD_RESOURCE_H_
+#define _BIRD_RESOURCE_H_
+
+#include <lib/lists.h>
+
+/* Resource */
+
+typedef struct resource {
+ node n; /* Inside resource pool */
+ struct resclass *class; /* Resource class */
+} resource;
+
+/* Resource class */
+
+struct resclass {
+ char *name; /* Resource class name */
+ unsigned size; /* Standard size of single resource */
+ void (*free)(resource *); /* Freeing function */
+ void (*dump)(resource *); /* Dump to debug output */
+};
+
+/* Generic resource manipulation */
+
+typedef struct pool pool;
+
+pool *rp_new(pool *); /* Create new pool */
+void rp_init(pool *); /* Initialize static pool */
+void rp_empty(pool *); /* Free everything in the pool */
+void rfree(void *); /* Free single resource */
+void rdump(void *); /* Dump to debug output */
+
+void ralloc(pool *, struct resclass *);
+
+/* Normal memory blocks */
+
+void *mb_alloc(pool *, unsigned size);
+void *mb_free(void *);
+
+/* Memory pools with linear allocation */
+
+typedef struct mempool mempool;
+
+mempool *mp_new(pool *, unsigned blk);
+void mp_trim(pool *); /* Free unused memory */
+void *mp_alloc(mempool *, unsigned size); /* Aligned */
+void *mp_allocu(mempool *, unsigned size); /* Unaligned */
+void *mp_allocz(mempool *, unsigned size); /* With clear */
+
+/* Slabs */
+
+typedef struct slab slab;
+
+slab *sl_new(pool *, unsigned size);
+void *sl_alloc(slab *);
+void sl_free(slab *, void *);
+
+/* Low-level memory allocation functions, please don't use */
+
+void *xmalloc(unsigned);
+#define xfree(x) free(x)
+
+#endif
diff --git a/lib/socket.h b/lib/socket.h
new file mode 100644
index 00000000..4f68a161
--- /dev/null
+++ b/lib/socket.h
@@ -0,0 +1,16 @@
+/*
+ * BIRD Socket Interface
+ *
+ * (c) 1998 Martin Mares <mj@ucw.cz>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#ifndef _BIRD_SOCKET_H_
+#define _BIRD_SOCKET_H_
+
+#include <lib/resource.h>
+
+typedef struct birdsock socket;
+
+#endif
diff --git a/lib/timer.h b/lib/timer.h
new file mode 100644
index 00000000..29f20c4b
--- /dev/null
+++ b/lib/timer.h
@@ -0,0 +1,26 @@
+/*
+ * BIRD Timers
+ *
+ * (c) 1998 Martin Mares <mj@ucw.cz>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#ifndef _BIRD_TIMER_H_
+#define _BIRD_TIMER_H_
+
+#include <lib/resource.h>
+
+typedef struct timer {
+ resource r;
+ void (*hook)(struct timer *);
+ void *data;
+ /* internal fields should be here */
+} timer;
+
+timer *tm_new(pool *, void (*hook)(timer *), void *data);
+void tm_start(timer *, unsigned after);
+void tm_stop(timer *);
+void tm_trigger(timer *);
+
+#endif
diff --git a/lib/unaligned.h b/lib/unaligned.h
new file mode 100644
index 00000000..29fcee99
--- /dev/null
+++ b/lib/unaligned.h
@@ -0,0 +1,12 @@
+/*
+ * Unaligned Data Accesses
+ *
+ * (c) 1998 Martin Mares <mj@ucw.cz>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#ifndef _BIRD_UNALIGNED_H_
+#define _BIRD_UNALIGNED_H_
+
+#endif
diff --git a/nest/Makefile b/nest/Makefile
new file mode 100644
index 00000000..d6c0e6ef
--- /dev/null
+++ b/nest/Makefile
@@ -0,0 +1,3 @@
+OBJS=main.o
+
+include $(TOPDIR)/Rules
diff --git a/nest/bird.h b/nest/bird.h
new file mode 100644
index 00000000..e8c33189
--- /dev/null
+++ b/nest/bird.h
@@ -0,0 +1,24 @@
+/*
+ * BIRD Internet Routing Daemon -- Basic Declarations
+ *
+ * (c) 1998 Martin Mares <mj@ucw.cz>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#ifndef _BIRD_BIRD_H_
+#define _BIRD_BIRD_H_
+
+#include <sysdep/config.h>
+#include <lib/birdlib.h>
+
+#ifndef IPV6
+#include <nest/ipv4.h>
+#else
+#include <nest/ipv6.h>
+#endif
+
+extern u32 router_id; /* Our Router ID */
+extern u16 this_as; /* Our Autonomous System Number */
+
+#endif
diff --git a/nest/confile.h b/nest/confile.h
new file mode 100644
index 00000000..1089e76a
--- /dev/null
+++ b/nest/confile.h
@@ -0,0 +1,12 @@
+/*
+ * BIRD Internet Routing Daemon -- Configuration File
+ *
+ * (c) 1998 Martin Mares <mj@ucw.cz>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#ifndef _BIRD_CONFILE_H_
+#define _BIRD_CONFILE_H_
+
+#endif
diff --git a/nest/iface.h b/nest/iface.h
new file mode 100644
index 00000000..2d0d7573
--- /dev/null
+++ b/nest/iface.h
@@ -0,0 +1,12 @@
+/*
+ * BIRD Internet Routing Daemon -- Network Interfaces
+ *
+ * (c) 1998 Martin Mares <mj@ucw.cz>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#ifndef _BIRD_IFACE_H_
+#define _BIRD_IFACE_H_
+
+#endif
diff --git a/nest/ipv4.h b/nest/ipv4.h
new file mode 100644
index 00000000..75242298
--- /dev/null
+++ b/nest/ipv4.h
@@ -0,0 +1,20 @@
+/*
+ * BIRD -- IP Addresses et Cetera for IPv4
+ *
+ * (c) 1998 Martin Mares <mj@ucw.cz>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#ifndef _BIRD_IPV4_H_
+#define _BIRD_IPV4_H_
+
+#include <netinet/in.h>
+
+typedef struct ipv4_addr {
+ u32 addr;
+} ip_addr;
+
+#define ipa_equal(x,y) ((x).addr == (y).addr)
+
+#endif
diff --git a/nest/ipv6.h b/nest/ipv6.h
new file mode 100644
index 00000000..5d5e3544
--- /dev/null
+++ b/nest/ipv6.h
@@ -0,0 +1,21 @@
+/*
+ * BIRD -- IP Addresses et Cetera for IPv6
+ *
+ * (c) 1998 Martin Mares <mj@ucw.cz>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#ifndef _BIRD_IPV4_H_
+#define _BIRD_IPV4_H_
+
+#include <netinet/in.h>
+#include <string.h>
+
+typedef struct ipv4_addr {
+ u32 addr[4];
+} ip_addr;
+
+#define ipa_equal(x,y) (!memcmp(&(x),&(y),sizeof(ip_addr)))
+
+#endif
diff --git a/nest/main.c b/nest/main.c
new file mode 100644
index 00000000..8f60f272
--- /dev/null
+++ b/nest/main.c
@@ -0,0 +1,23 @@
+/*
+ * BIRD Internet Routing Daemon
+ *
+ * (c) 1998 Martin Mares <mj@ucw.cz>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include <nest/bird.h>
+#include <lib/lists.h>
+
+#include <nest/resource.h>
+
+int
+main(void)
+{
+ ip_addr x,y;
+
+ x=y;
+ if (ipa_equal(x,y)) return 1;
+
+ return 0;
+}
diff --git a/nest/protocol.h b/nest/protocol.h
new file mode 100644
index 00000000..adca1149
--- /dev/null
+++ b/nest/protocol.h
@@ -0,0 +1,66 @@
+/*
+ * BIRD Internet Routing Daemon -- Protocols
+ *
+ * (c) 1998 Martin Mares <mj@ucw.cz>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#ifndef _BIRD_PROTOCOL_H_
+#define _BIRD_PROTOCOL_H_
+
+#include <lib/resource.h>
+
+/*
+ * Routing Protocol
+ */
+
+struct protocol {
+ char *name;
+ unsigned type; /* ??? List values ??? */
+ unsigned debug; /* Default debugging flags */
+
+ void (*init)(struct protocol *); /* Boot time */
+ void (*preconfig)(struct protocol *); /* Just before configuring */
+ void (*postconfig)(struct protocol *); /* After configuring */
+};
+
+void protos_init(void);
+void protos_preconfig(void);
+void protos_postconfig(void);
+
+/*
+ * Known protocols
+ */
+
+extern struct protocol proto_static;
+
+/*
+ * Routing Protocol Instance
+ */
+
+struct proto {
+ struct proto *next;
+ struct protocol *proto; /* Protocol */
+ char *name; /* Name of this instance */
+ unsigned debug; /* Debugging flags */
+ pool *pool; /* Local objects */
+ unsigned preference; /* Default route preference */
+
+ void (*if_notify)(struct proto *, struct iface *old, struct iface *new);
+ void (*rt_notify)(struct proto *, struct rte *old, struct rte *new);
+ void (*debug)(struct proto *); /* Debugging dump */
+ void (*start)(struct proto *); /* Start the instance */
+ void (*shutdown)(struct proto *, int time); /* Stop the instance */
+
+ /* Reconfigure function? */
+ /* Interface patterns */
+ /* Input/output filters */
+ /* Connection to routing tables? */
+
+ /* Hic sunt protocol-specific data */
+};
+
+void *proto_new(struct protocol *, unsigned size);
+
+#endif
diff --git a/nest/route.h b/nest/route.h
new file mode 100644
index 00000000..e968e12a
--- /dev/null
+++ b/nest/route.h
@@ -0,0 +1,190 @@
+/*
+ * BIRD Internet Routing Daemon -- Routing Table
+ *
+ * (c) 1998 Martin Mares <mj@ucw.cz>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#ifndef _BIRD_ROUTE_H_
+#define _BIRD_ROUTE_H_
+
+#include <lib/resource.h>
+
+/*
+ * Generic data structure for storing network prefixes. Also used
+ * for the master routing table. Currently implemented as a radix
+ * trie.
+ *
+ * Available operations:
+ * - insertion of new entry
+ * - deletion of entry
+ * - searching of entry by network prefix
+ * - searching of entry by IP address (longest match)
+ */
+
+struct fib_node {
+ ip_addr prefix; /* In host order */
+ byte pxlen;
+ byte flags; /* ??? define them ??? */
+ byte pad0, pad1; /* ??? use ??? */
+ struct fib_node *left, *right, *up; /* Radix Trie links */
+};
+
+struct fib {
+ slab fib_slab; /* Slab holding all fib nodes */
+ struct fib_node root;
+ void (*init)(struct fib_node *); /* Constructor */
+};
+
+void fib_init(struct fib *, pool *, unsigned node_size, void (*init)(struct fib_node *));
+void *fib_find(struct fib *, ip_addr *, int); /* Find or return NULL if doesn't exist */
+void *fib_find_ip(struct fib *, ip_addr *); /* Longest match (always exists) */
+void *fib_get(struct fib *, ip_addr *, int); /* Find or create new if nonexistent */
+void fib_delete(struct fib *);
+
+/*
+ * Master Routing Table. Generally speaking, it's a FIB with each entry
+ * pointing to a list of route entries representing routes to given network.
+ * Each of the RTE's contains variable data (the preference and protocol-dependent
+ * metrics) and a pointer to route attribute block common for many routes).
+ */
+
+typedef struct network {
+ struct fib_node n;
+ struct rte *routes; /* Available routes for this network */
+ struct network *next; /* Next in Recalc Chain */
+} net;
+
+typedef struct rte {
+ struct rte *next;
+ struct rtattr *attrs;
+ byte flags; /* Flags (REF_...) */
+ byte rfu;
+ word pref; /* Route preference */
+ union { /* Protocol-dependent data (metrics etc.) */
+#ifdef CONFIG_STATIC
+ struct {
+ } stat;
+#endif
+#ifdef CONFIG_RIP
+ struct {
+ byte metric; /* RIP metric */
+ } rip;
+#endif
+#ifdef CONFIG_OSPF
+ struct {
+ u32 metric1, metric2; /* OSPF Type 1 and Type 2 metrics */
+ } ospf;
+#endif
+#ifdef CONFIG_BGP
+ struct {
+ } bgp;
+#endif
+ } u;
+} rte;
+
+#define REF_CHOSEN 1 /* Currently chosen route */
+
+typedef struct rte rte;
+
+/*
+ * Route Attributes
+ *
+ * Beware: All standard BGP attributes must be represented here instead
+ * of making them local to the route. This is needed to ensure proper
+ * construction of BGP route attribute lists.
+ */
+
+struct rtattr {
+ struct rtattr *next, *prev; /* Hash chain */
+ struct rtattr *garbage; /* Garbage collector chain */
+ struct proto *proto; /* Protocol instance */
+ unsigned uc; /* Use count */
+ byte source; /* Route source (RTS_...) */
+ byte scope; /* Route scope (SCOPE_...) */
+ byte cast; /* Casting type (RTC_...) */
+ byte dest; /* Route destination type (RTD_...) */
+ byte tos; /* TOS of this route */
+ byte flags; /* Route flags (RTF_...) */
+ word source_as; /* Source AS of this route (0=local) */
+ ip_addr gw; /* Next hop */
+ struct iface *iface; /* Outgoing interface */
+ struct ea_list *attrs; /* Extended Attribute chain */
+} rta;
+
+#define RTS_STATIC 1 /* Normal static route */
+#define RTS_INHERIT 2 /* Route inherited from kernel */
+#define RTS_DEVICE 3 /* Device route */
+#define RTS_STATIC_DEVICE 4 /* Static device route */
+#define RTS_REDIRECT 5 /* Learned via redirect */
+#define RTS_RIP 6 /* RIP route */
+#define RTS_RIP_EXT 7 /* RIP external route */
+#define RTS_OSPF 8 /* OSPF route */
+#define RTS_OSPF_EXT 9 /* OSPF external route */
+#define RTS_OSPF_IA 10 /* OSPF inter-area route */
+#define RTS_OSPF_BOUNDARY 11 /* OSPF route to boundary router */
+#define RTS_BGP 12 /* BGP route */
+
+#define SCOPE_HOST 0 /* Address scope */
+#define SCOPE_LINK 0x10
+#define SCOPE_SITE 0x80
+#define SCOPE_UNIVERSE 0xff
+
+#define RTC_UNICAST 0
+#define RTC_BROADCAST 1
+#define RTC_MULTICAST 2
+#define RTC_ANYCAST 3 /* IPv6 Anycast */
+
+#define RTD_ROUTER 0 /* Next hop is neighbor router */
+#define RTD_DEVICE 1 /* Points to device */
+#define RTD_BLACKHOLE 2 /* Silently drop packets */
+#define RTD_UNREACHABLE 3 /* Reject as unreachable */
+#define RTD_PROHIBIT 4 /* Administratively prohibited */
+
+/*
+ * Extended Route Attributes
+ */
+
+typedef struct eattr {
+ byte protocol; /* Protocol ID (EAP_...) */
+ byte flags; /* Attribute flags (EAF_...) */
+ byte id; /* Protocol-dependent ID */
+ union {
+ u32 data;
+ struct adata *ptr; /* Attribute data elsewhere */
+ } u;
+} eattr;
+
+#define EAP_GENERIC 0 /* Generic attributes */
+#define EAP_BGP 1 /* BGP attributes */
+
+#define EAF_OPTIONAL 0x80 /* Refer to BGP specs for full meaning */
+#define EAF_TRANSITIVE 0x40
+#define EAF_PARTIAL 0x20
+#define EAF_EXTENDED_LENGTH 0x10 /* Not used by us, internal to BGP */
+#define EAF_LONGWORD 0x01 /* Embedded value [Not a BGP flag!] */
+
+struct adata {
+ unsigned int length;
+ byte data[0];
+};
+
+typedef struct ea_list {
+ struct ea_list *next; /* In case we have an override list */
+ byte sorted; /* `Really sorted' flag */
+ byte rfu;
+ word nattrs; /* Number of attributes */
+ eattr attrs[0]; /* Attribute definitions themselves */
+} ea_list;
+
+eattr *ea_find(ea_list *, unsigned protocol, unsigned id);
+
+#define EA_LIST_NEW(p, alloc, n) do { \
+ unsigned cnt = n; \
+ p = alloc(sizeof(ea_list) + cnt*sizeof(eattr)); \
+ memset(p, sizeof(ea_list)); \
+ p->nattrs = cnt; \
+} while(0)
+
+#endif
diff --git a/sysdep/cf/linux-20.h b/sysdep/cf/linux-20.h
new file mode 100644
index 00000000..6100add3
--- /dev/null
+++ b/sysdep/cf/linux-20.h
@@ -0,0 +1,11 @@
+/*
+ * Configuration for Linux 2.0 based systems
+ *
+ * (c) 1998 Martin Mares <mj@ucw.cz>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#undef CONFIG_TOS
+#undef CONFIG_MULTIPATH
+#undef CONFIG_NETLINK
diff --git a/sysdep/cf/linux-21.h b/sysdep/cf/linux-21.h
new file mode 100644
index 00000000..a2afcbbd
--- /dev/null
+++ b/sysdep/cf/linux-21.h
@@ -0,0 +1,11 @@
+/*
+ * Configuration for Linux 2.1 based systems
+ *
+ * (c) 1998 Martin Mares <mj@ucw.cz>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#define CONFIG_TOS
+#define CONFIG_MULTIPATH
+#define CONFIG_NETLINK
diff --git a/sysdep/cf/linux-v6.h b/sysdep/cf/linux-v6.h
new file mode 100644
index 00000000..de397fc1
--- /dev/null
+++ b/sysdep/cf/linux-v6.h
@@ -0,0 +1,13 @@
+/*
+ * Configuration for Linux 2.1 based systems running IPv6
+ *
+ * (c) 1998 Martin Mares <mj@ucw.cz>
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#define IPV6
+
+#define CONFIG_TOS
+#define CONFIG_MULTIPATH
+#define CONFIG_NETLINK
diff --git a/sysdep/config.h b/sysdep/config.h
new file mode 100644
index 00000000..e83a5088
--- /dev/null
+++ b/sysdep/config.h
@@ -0,0 +1,50 @@
+/*
+ * This is a manually generated BIRD configuration file.
+ * It will be replaced by something better when we come
+ * with an automated configuration mechanism. [mj]
+ */
+
+#ifndef _BIRD_CONFIG_H_
+#define _BIRD_CONFIG_H_
+
+/* System-dependent configuration */
+
+#include <sysdep/cf/linux-20.h>
+
+/* Include debugging code */
+
+#define DEBUG
+
+/* Types */
+
+typedef signed char s8;
+typedef unsigned char u8;
+typedef short int s16;
+typedef unsigned short int u16;
+typedef int s32;
+typedef unsigned int u32;
+
+typedef u8 byte;
+typedef u16 word;
+
+/* Endianity */
+
+#define CPU_LITTLE_ENDIAN
+
+/* Required alignment for multi-byte accesses */
+
+#define CPU_NEEDS_ALIGN_WORD 1
+#define CPU_NEEDS_ALIGN_LONG 1
+
+/* Usual alignment for structures */
+
+#define CPU_STRUCT_ALIGN 4
+
+/* Protocol options */
+
+#define CONFIG_STATIC
+#define CONFIG_RIP
+#define CONFIG_BGP
+#define CONFIG_OSPF
+
+#endif
diff --git a/sysdep/linux/Makefile b/sysdep/linux/Makefile
new file mode 100644
index 00000000..a81db06d
--- /dev/null
+++ b/sysdep/linux/Makefile
@@ -0,0 +1 @@
+include $(TOPDIR)/Rules