Commit 696b2f2a authored by Jondy Zhao's avatar Jondy Zhao

Add babeld sources.

parent f9323891
This diff is collapsed.
Copyright (c) 2007, 2008 by Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
PREFIX = /usr/local
CDEBUGFLAGS = -Os -g -Wall
DEFINES = $(PLATFORM_DEFINES)
CFLAGS = $(CDEBUGFLAGS) $(DEFINES) $(EXTRA_DEFINES)
LDLIBS = -lrt
SRCS = babeld.c net.c kernel.c util.c interface.c source.c neighbour.c \
route.c xroute.c message.c resend.c configuration.c local.c
OBJS = babeld.o net.o kernel.o util.o interface.o source.o neighbour.o \
route.o xroute.o message.o resend.o configuration.o local.o
babeld: $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) -o babeld $(OBJS) $(LDLIBS)
.SUFFIXES: .man .html
.man.html:
rman -f html $< | \
sed -e "s|<a href='babeld.8'|<a href=\"babeld.html\"|" \
-e "s|<a href='\\(ahcp[-a-z]*\\).8'|<a href=\"../ahcp/\1.html\"|" \
-e "s|<a href='[^']*8'>\\(.*(8)\\)</a>|\1|" \
> $@
babeld.html: babeld.man
.PHONY: all install install.minimal uninstall clean
all: babeld babeld.man
install.minimal: babeld
-rm -f $(TARGET)$(PREFIX)/bin/babeld
mkdir -p $(TARGET)$(PREFIX)/bin
cp -f babeld $(TARGET)$(PREFIX)/bin
install: install.minimal all
mkdir -p $(TARGET)$(PREFIX)/man/man8
cp -f babeld.man $(TARGET)$(PREFIX)/man/man8/babeld.8
uninstall:
-rm -f $(TARGET)$(PREFIX)/bin/babeld
-rm -f $(TARGET)$(PREFIX)/man/man8/babeld.8
clean:
-rm -f babeld babeld.html *.o *~ core TAGS gmon.out
kernel.o: kernel_netlink.c kernel_socket.c
Babel
=====
Babel is a loop-avoiding distance-vector routing protocol roughly
based on HSDV and AODV, but with provisions for link cost estimation
and redistribution of routes from other routing protocols.
Installation
============
$ make
$ su -c 'make install'
If compiling for OpenWRT, you will probably want to say something like
$ make CC=mipsel-linux-gcc PLATFORM_DEFINES='-march=mips32'
On Mac OS X, you'll need to do
$ make LDLIBS=''
Setting up a network for use with Babel
=======================================
1. Set up every node's interface
--------------------------------
On every node, set up the wireless interface:
# iwconfig eth1 mode ad-hoc channel 11 essid "my-mesh-network"
# ip link set up dev eth1
2. Set up every node's IP addresses
-----------------------------------
You will need to make sure that all of your nodes have a unique IPv6
address, and/or a unique IPv4 address.
On every node, run something like:
# ip addr add 192.168.13.33/32 dev eth1
# ip -6 addr add $(generate-ipv6-address -r)/128 dev eth1
You will find the generate-ipv6-address utility, which can generate random
IPv6 addresses according to RFC 4193, on
http://www.pps.jussieu.fr/~jch/software/files/
A note about tunnels and VPNs
-----------------------------
Some VPN implementations (notably OpenVPN and Linux GRE) do not
automatically add an IPv6 link-local address to the tunnel interface.
If you attempt to run Babel over such an interface, it will complain
that it ``couldn't allocate requested address''.
The solution is to manually add the link-local address to the
interface. This can be done by running e.g.
# ip -6 addr add $(ahcp-generate-address fe80::) dev gre0
3. Start the routing daemon
---------------------------
Run Babel on every node, specifying the set of interfaces that it
should consider:
# babeld eth1
If your node has multiple interfaces which you want to participate in
the Babel network, just list them all:
# babeld eth0 eth1 sit1
4. Setting up an Internet gateway
---------------------------------
If you have one or more Internet gateways on your mesh network, you
will want to set them up so that they redistribute the default route.
Babel will only redistribute routes with an explicit protocol
attached, so you must say something like:
# ip route add 0.0.0.0/0 via 1.2.3.4 dev eth0 proto static
In order to redistribute all routes, you will say:
# babeld -C 'redistribute metric 128' eth1
You may also be more selective in the routes you redistribute, for
instance by specifying the interface over which the route goes out:
# babeld -C 'redistribute if eth0 metric 128' eth1
or by constraining the prefix length:
# babeld -C 'redistribute ip ::/0 le 64 metric 128' \
-C 'redistribute ip 0.0.0.0/0 le 28 metric 128' \
eth1
You may also want to constrain which local routes (routes to local
interface addresses) you advertise:
# babeld -C 'redistribute local if eth1' -C 'redistribute local deny' \
-C 'redistribute metric 128' \
eth1
If you find all of this too complicated and error-prone (as I do), you
may want to consider autoconfiguring your routing domain using AHCP:
http://www.pps.jussieu.fr/~jch/software/ahcp/
-- Juliusz Chroboczek
This diff is collapsed.
/*
Copyright (c) 2007, 2008 by Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#define INFINITY ((unsigned short)(~0))
#ifndef RTPROT_BABEL
#define RTPROT_BABEL 42
#endif
#define RTPROT_BABEL_LOCAL -2
#undef MAX
#undef MIN
#define MAX(x,y) ((x)<=(y)?(y):(x))
#define MIN(x,y) ((x)<=(y)?(x):(y))
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
/* nothing */
#elif defined(__GNUC__)
#define inline __inline
#if (__GNUC__ >= 3)
#define restrict __restrict
#else
#define restrict /**/
#endif
#else
#define inline /**/
#define restrict /**/
#endif
#if defined(__GNUC__) && (__GNUC__ >= 3)
#define ATTRIBUTE(x) __attribute__ (x)
#define LIKELY(_x) __builtin_expect(!!(_x), 1)
#define UNLIKELY(_x) __builtin_expect(!!(_x), 0)
#else
#define ATTRIBUTE(x) /**/
#define LIKELY(_x) !!(_x)
#define UNLIKELY(_x) !!(_x)
#endif
#if defined(__GNUC__) && (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 3)
#define COLD __attribute__ ((cold))
#else
#define COLD /**/
#endif
#ifndef IF_NAMESIZE
#include <sys/socket.h>
#include <net/if.h>
#endif
#ifdef HAVE_VALGRIND
#include <valgrind/memcheck.h>
#else
#ifndef VALGRIND_MAKE_MEM_UNDEFINED
#define VALGRIND_MAKE_MEM_UNDEFINED(a, b) do {} while(0)
#endif
#ifndef VALGRIND_CHECK_MEM_IS_DEFINED
#define VALGRIND_CHECK_MEM_IS_DEFINED(a, b) do {} while(0)
#endif
#endif
extern struct timeval now;
extern int debug;
extern time_t reboot_time;
extern int default_wireless_hello_interval, default_wired_hello_interval;
extern int resend_delay;
extern int link_detect;
extern int all_wireless;
extern int local_socket;
extern unsigned char myid[8];
extern const unsigned char zeroes[16], ones[16];
extern int protocol_port;
extern unsigned char protocol_group[16];
extern int protocol_socket;
extern int kernel_socket;
extern int max_request_hopcount;
void schedule_neighbours_check(int msecs, int override);
int resize_receive_buffer(int size);
This diff is collapsed.
This diff is collapsed.
/*
Copyright (c) 2007, 2008 by Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
struct filter {
int af;
char *ifname;
unsigned int ifindex;
unsigned char *id;
unsigned char *prefix;
unsigned char plen;
unsigned char plen_ge, plen_le;
unsigned char *neigh;
int proto; /* May be negative */
unsigned int result;
struct filter *next;
};
int parse_config_from_file(char *filename);
int parse_config_from_string(char *string);
void renumber_filters(void);
int input_filter(const unsigned char *id,
const unsigned char *prefix, unsigned short plen,
const unsigned char *neigh, unsigned int ifindex);
int output_filter(const unsigned char *id, const unsigned char *prefix,
unsigned short plen, unsigned int ifindex);
int redistribute_filter(const unsigned char *prefix, unsigned short plen,
unsigned int ifindex, int proto);
int finalise_config(void);
This diff is collapsed.
/*
Copyright (c) 2007, 2008 by Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
struct buffered_update {
unsigned char id[8];
unsigned char prefix[16];
unsigned char plen;
unsigned char pad[3];
};
struct interface_conf {
char *ifname;
unsigned hello_interval;
unsigned update_interval;
unsigned short cost;
char wired;
char split_horizon;
char lq;
char faraway;
int channel;
struct interface_conf *next;
};
#define CONFIG_DEFAULT 0
#define CONFIG_NO 1
#define CONFIG_YES 2
#define IF_UP (1 << 0)
#define IF_WIRED (1<<1)
#define IF_SPLIT_HORIZON (1 << 2)
#define IF_LQ (1 << 3)
#define IF_FARAWAY (1 << 4)
/* Only INTERFERING can appear on the wire. */
#define IF_CHANNEL_UNKNOWN 0
#define IF_CHANNEL_INTERFERING 255
#define IF_CHANNEL_NONINTERFERING -2
struct interface {
struct interface *next;
struct interface_conf *conf;
unsigned int ifindex;
unsigned short flags;
unsigned short cost;
int channel;
struct timeval hello_timeout;
struct timeval update_timeout;
struct timeval flush_timeout;
struct timeval update_flush_timeout;
char name[IF_NAMESIZE];
unsigned char *ipv4;
int numll;
unsigned char (*ll)[16];
int buffered;
int bufsize;
char have_buffered_hello;
char have_buffered_id;
char have_buffered_nh;
char have_buffered_prefix;
unsigned char buffered_id[16];
unsigned char buffered_nh[4];
unsigned char buffered_prefix[16];
unsigned char *sendbuf;
struct buffered_update *buffered_updates;
int num_buffered_updates;
int update_bufsize;
time_t bucket_time;
unsigned int bucket;
time_t last_update_time;
unsigned short hello_seqno;
unsigned hello_interval;
unsigned update_interval;
};
#define IF_CONF(_ifp, _field) \
((_ifp)->conf ? (_ifp)->conf->_field : 0)
extern struct interface *interfaces;
#define FOR_ALL_INTERFACES(_ifp) for(_ifp = interfaces; _ifp; _ifp = _ifp->next)
static inline int
if_up(struct interface *ifp)
{
return !!(ifp->flags & IF_UP);
}
struct interface *add_interface(char *ifname, struct interface_conf *if_conf);
unsigned jitter(struct interface *ifp, int urgent);
unsigned update_jitter(struct interface *ifp, int urgent);
void set_timeout(struct timeval *timeout, int msecs);
int interface_up(struct interface *ifp, int up);
int interface_ll_address(struct interface *ifp, const unsigned char *address);
void check_interfaces(void);
/*
Copyright 2007, 2008 by Grégoire Henry, Julien Cristau and Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include <sys/time.h>
#include <sys/param.h>
#include <time.h>
#include "babeld.h"
#ifdef __linux
#include "kernel_netlink.c"
#else
#include "kernel_socket.c"
#endif
/* Like gettimeofday, but returns monotonic time. If POSIX clocks are not
available, falls back to gettimeofday but enforces monotonicity. */
int
gettime(struct timeval *tv)
{
int rc;
static time_t offset = 0, previous = 0;
#if defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0 && defined(CLOCK_MONOTONIC)
static int have_posix_clocks = -1;
if(UNLIKELY(have_posix_clocks < 0)) {
struct timespec ts;
rc = clock_gettime(CLOCK_MONOTONIC, &ts);
if(rc < 0) {
have_posix_clocks = 0;
} else {
have_posix_clocks = 1;
}
}
if(have_posix_clocks) {
struct timespec ts;
int rc;
rc = clock_gettime(CLOCK_MONOTONIC, &ts);
if(rc < 0)
return rc;
tv->tv_sec = ts.tv_sec;
tv->tv_usec = ts.tv_nsec / 1000;
return rc;
}
#endif
rc = gettimeofday(tv, NULL);
if(rc < 0)
return rc;
tv->tv_sec += offset;
if(UNLIKELY(previous > tv->tv_sec)) {
offset += previous - tv->tv_sec;
tv->tv_sec = previous;
}
previous = tv->tv_sec;
return rc;
}
/* If /dev/urandom doesn't exist, this will fail with ENOENT, which the
caller will deal with gracefully. */
int
read_random_bytes(void *buf, size_t len)
{
int fd;
int rc;
fd = open("/dev/urandom", O_RDONLY);
if(fd < 0) {
rc = -1;
} else {
rc = read(fd, buf, len);
if(rc < 0 || (unsigned)rc < len)
rc = -1;
close(fd);
}
return rc;
}
/*
Copyright (c) 2007, 2008 by Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include <netinet/in.h>
#include "babeld.h"
#define KERNEL_INFINITY 0xFFFF
struct kernel_route {
unsigned char prefix[16];
int plen;
int metric;
unsigned int ifindex;
int proto;
unsigned char gw[16];
};
#define ROUTE_FLUSH 0
#define ROUTE_ADD 1
#define ROUTE_MODIFY 2
#define CHANGE_LINK (1 << 0)
#define CHANGE_ROUTE (1 << 1)
#define CHANGE_ADDR (1 << 2)
extern int export_table, import_table;
int kernel_setup(int setup);
int kernel_setup_socket(int setup);
int kernel_setup_interface(int setup, const char *ifname, int ifindex);
int kernel_interface_operational(const char *ifname, int ifindex);
int kernel_interface_ipv4(const char *ifname, int ifindex,
unsigned char *addr_r);
int kernel_interface_mtu(const char *ifname, int ifindex);
int kernel_interface_wireless(const char *ifname, int ifindex);
int kernel_interface_channel(const char *ifname, int ifindex);
int kernel_route(int operation, const unsigned char *dest, unsigned short plen,
const unsigned char *gate, int ifindex, unsigned int metric,
const unsigned char *newgate, int newifindex,
unsigned int newmetric);
int kernel_routes(struct kernel_route *routes, int maxroutes);
int kernel_callback(int (*fn)(int, void*), void *closure);
int kernel_addresses(char *ifname, int ifindex, int ll,
struct kernel_route *routes, int maxroutes);
int if_eui64(char *ifname, int ifindex, unsigned char *eui);
int gettime(struct timeval *tv);
int read_random_bytes(void *buf, size_t len);
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment