Add the Babel routing protocol (RFC 6126)
This patch implements the IPv6 subset of the Babel routing protocol. Based on the patch from Toke Hoiland-Jorgensen, with some heavy modifications and bugfixes. Thanks to Toke Hoiland-Jorgensen for the original patch.
This commit is contained in:
parent
a7baa09862
commit
937e75d8f1
19 changed files with 3767 additions and 10 deletions
|
@ -206,6 +206,9 @@ fi
|
||||||
AC_SUBST(iproutedir)
|
AC_SUBST(iproutedir)
|
||||||
|
|
||||||
all_protocols="$proto_bfd bgp ospf pipe $proto_radv rip static"
|
all_protocols="$proto_bfd bgp ospf pipe $proto_radv rip static"
|
||||||
|
if test "$ip" = ipv6 ; then
|
||||||
|
all_protocols="$all_protocols babel"
|
||||||
|
fi
|
||||||
all_protocols=`echo $all_protocols | sed 's/ /,/g'`
|
all_protocols=`echo $all_protocols | sed 's/ /,/g'`
|
||||||
|
|
||||||
if test "$with_protocols" = all ; then
|
if test "$with_protocols" = all ; then
|
||||||
|
|
|
@ -1380,6 +1380,102 @@ corresponding protocol sections.
|
||||||
|
|
||||||
<chapt>Protocols
|
<chapt>Protocols
|
||||||
|
|
||||||
|
<sect>Babel
|
||||||
|
|
||||||
|
<sect1>Introduction
|
||||||
|
|
||||||
|
<p>The Babel protocol (RFC6126) is a loop-avoiding distance-vector routing
|
||||||
|
protocol that is robust and efficient both in ordinary wired networks and in
|
||||||
|
wireless mesh networks. Babel is conceptually very simple in its operation and
|
||||||
|
"just works" in its default configuration, though some configuration is possible
|
||||||
|
and in some cases desirable.
|
||||||
|
|
||||||
|
<p>While the Babel protocol is dual stack (i.e., can carry both IPv4 and IPv6
|
||||||
|
routes over the same IPv6 transport), BIRD presently implements only the IPv6
|
||||||
|
subset of the protocol. No Babel extensions are implemented, but the BIRD
|
||||||
|
implementation can coexist with implementations using the extensions (and will
|
||||||
|
just ignore extension messages).
|
||||||
|
|
||||||
|
<p>The Babel protocol implementation in BIRD is currently in alpha stage.
|
||||||
|
|
||||||
|
<sect1>Configuration
|
||||||
|
|
||||||
|
<p>Babel supports no global configuration options apart from those common to all
|
||||||
|
other protocols, but supports the following per-interface configuration options:
|
||||||
|
|
||||||
|
<code>
|
||||||
|
protocol babel [<name>] {
|
||||||
|
interface <interface pattern> {
|
||||||
|
type <wired|wireless>;
|
||||||
|
rxcost <number>;
|
||||||
|
hello interval <number>;
|
||||||
|
update interval <number>;
|
||||||
|
port <number>;
|
||||||
|
tx class|dscp <number>;
|
||||||
|
tx priority <number>;
|
||||||
|
rx buffer <number>;
|
||||||
|
tx length <number>;
|
||||||
|
check link <switch>;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</code>
|
||||||
|
|
||||||
|
<descrip>
|
||||||
|
<tag>type wired|wireless </tag>
|
||||||
|
This option specifies the interface type: Wired or wireless. Wired
|
||||||
|
interfaces are considered more reliable, and so the default hello
|
||||||
|
interval is higher, and a neighbour is considered unreachable after only
|
||||||
|
a small number of "hello" packets are lost. On wireless interfaces,
|
||||||
|
hello packets are sent more often, and the ETX link quality estimation
|
||||||
|
technique is used to compute the metrics of routes discovered over this
|
||||||
|
interface. This technique will gradually degrade the metric of routes
|
||||||
|
when packets are lost rather than the more binary up/down mechanism of
|
||||||
|
wired type links. Default: <cf/wired/.
|
||||||
|
|
||||||
|
<tag>rxcost <m/num/</tag>
|
||||||
|
This specifies the RX cost of the interface. The route metrics will be
|
||||||
|
computed from this value with a mechanism determined by the interface
|
||||||
|
<cf/type/. Default: 96 for wired interfaces, 256 for wireless.
|
||||||
|
|
||||||
|
<tag>hello interval <m/num/</tag>
|
||||||
|
Interval at which periodic "hello" messages are sent on this interface,
|
||||||
|
in seconds. Default: 4 seconds.
|
||||||
|
|
||||||
|
<tag>update interval <m/num/</tag>
|
||||||
|
Interval at which periodic (full) updates are sent. Default: 4 times the
|
||||||
|
hello interval.
|
||||||
|
|
||||||
|
<tag>port <m/number/</tag>
|
||||||
|
This option selects an UDP port to operate on. The default is to operate
|
||||||
|
on port 6696 as specified in the Babel RFC.
|
||||||
|
|
||||||
|
<tag>tx class|dscp|priority <m/number/</tag>
|
||||||
|
These options specify the ToS/DiffServ/Traffic class/Priority of the
|
||||||
|
outgoing Babel packets. See <ref id="dsc-prio" name="tx class"> common
|
||||||
|
option for detailed description.
|
||||||
|
|
||||||
|
<tag>rx buffer <m/number/</tag>
|
||||||
|
This option specifies the size of buffers used for packet processing.
|
||||||
|
The buffer size should be bigger than maximal size of received packets.
|
||||||
|
The default value is the interface MTU, and the value will be clamped to a
|
||||||
|
minimum of 512 bytes + IP packet overhead.
|
||||||
|
|
||||||
|
<tag>tx length <m/number/</tag>
|
||||||
|
This option specifies the maximum length of generated Babel packets. To
|
||||||
|
avoid IP fragmentation, it should not exceed the interface MTU value.
|
||||||
|
The default value is the interface MTU value, and the value will be
|
||||||
|
clamped to a minimum of 512 bytes + IP packet overhead.
|
||||||
|
|
||||||
|
<tag>check link <m/switch/</tag>
|
||||||
|
If set, the hardware link state (as reported by OS) is taken into
|
||||||
|
consideration. When the link disappears (e.g. an ethernet cable is
|
||||||
|
unplugged), neighbors are immediately considered unreachable and all
|
||||||
|
routes received from them are withdrawn. It is possible that some
|
||||||
|
hardware drivers or platforms do not implement this feature. Default:
|
||||||
|
yes.
|
||||||
|
</descrip>
|
||||||
|
|
||||||
|
|
||||||
<sect><label id="sect-bfd">BFD
|
<sect><label id="sect-bfd">BFD
|
||||||
|
|
||||||
<sect1>Introduction
|
<sect1>Introduction
|
||||||
|
|
|
@ -57,6 +57,9 @@ Reply codes of BIRD command-line interface
|
||||||
1020 Show BFD sessions
|
1020 Show BFD sessions
|
||||||
1021 Show RIP interface
|
1021 Show RIP interface
|
||||||
1022 Show RIP neighbors
|
1022 Show RIP neighbors
|
||||||
|
1023 Show Babel interfaces
|
||||||
|
1024 Show Babel neighbors
|
||||||
|
1025 Show Babel entries
|
||||||
|
|
||||||
8000 Reply too long
|
8000 Reply too long
|
||||||
8001 Route not found
|
8001 Route not found
|
||||||
|
|
|
@ -60,6 +60,7 @@
|
||||||
|
|
||||||
#define NORET __attribute__((noreturn))
|
#define NORET __attribute__((noreturn))
|
||||||
#define UNUSED __attribute__((unused))
|
#define UNUSED __attribute__((unused))
|
||||||
|
#define PACKED __attribute__((packed))
|
||||||
|
|
||||||
|
|
||||||
/* Microsecond time */
|
/* Microsecond time */
|
||||||
|
|
|
@ -25,5 +25,6 @@ u32 u32_log2(u32 v);
|
||||||
|
|
||||||
static inline u32 u32_hash(u32 v) { return v * 2902958171u; }
|
static inline u32 u32_hash(u32 v) { return v * 2902958171u; }
|
||||||
|
|
||||||
#endif
|
static inline u8 u32_popcount(u32 v) { return __builtin_popcount(v); }
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
1
lib/ip.h
1
lib/ip.h
|
@ -26,6 +26,7 @@
|
||||||
#define IP6_OSPF_ALL_ROUTERS ipa_build6(0xFF020000, 0, 0, 5)
|
#define IP6_OSPF_ALL_ROUTERS ipa_build6(0xFF020000, 0, 0, 5)
|
||||||
#define IP6_OSPF_DES_ROUTERS ipa_build6(0xFF020000, 0, 0, 6)
|
#define IP6_OSPF_DES_ROUTERS ipa_build6(0xFF020000, 0, 0, 6)
|
||||||
#define IP6_RIP_ROUTERS ipa_build6(0xFF020000, 0, 0, 9)
|
#define IP6_RIP_ROUTERS ipa_build6(0xFF020000, 0, 0, 9)
|
||||||
|
#define IP6_BABEL_ROUTERS ipa_build6(0xFF020000, 0, 0, 0x00010006)
|
||||||
|
|
||||||
#define IP4_NONE _MI4(0)
|
#define IP4_NONE _MI4(0)
|
||||||
#define IP6_NONE _MI6(0,0,0,0)
|
#define IP6_NONE _MI6(0,0,0,0)
|
||||||
|
|
19
lib/printf.c
19
lib/printf.c
|
@ -124,6 +124,7 @@ static char * number(char * str, long num, int base, int size, int precision,
|
||||||
* width is automatically replaced by standard IP address width which
|
* width is automatically replaced by standard IP address width which
|
||||||
* depends on whether we use IPv4 or IPv6; |%#I| gives hexadecimal format),
|
* depends on whether we use IPv4 or IPv6; |%#I| gives hexadecimal format),
|
||||||
* |%R| for Router / Network ID (u32 value printed as IPv4 address)
|
* |%R| for Router / Network ID (u32 value printed as IPv4 address)
|
||||||
|
* |%lR| for 64bit Router / Network ID (u64 value printed as eight :-separated octets)
|
||||||
* and |%m| resp. |%M| for error messages (uses strerror() to translate @errno code to
|
* and |%m| resp. |%M| for error messages (uses strerror() to translate @errno code to
|
||||||
* message text). On the other hand, it doesn't support floating
|
* message text). On the other hand, it doesn't support floating
|
||||||
* point numbers.
|
* point numbers.
|
||||||
|
@ -137,9 +138,10 @@ int bvsnprintf(char *buf, int size, const char *fmt, va_list args)
|
||||||
unsigned long num;
|
unsigned long num;
|
||||||
int i, base;
|
int i, base;
|
||||||
u32 x;
|
u32 x;
|
||||||
|
u64 X;
|
||||||
char *str, *start;
|
char *str, *start;
|
||||||
const char *s;
|
const char *s;
|
||||||
char ipbuf[STD_ADDRESS_P_LENGTH+1];
|
char ipbuf[MAX(STD_ADDRESS_P_LENGTH,ROUTER_ID_64_LENGTH)+1];
|
||||||
struct iface *iface;
|
struct iface *iface;
|
||||||
|
|
||||||
int flags; /* flags to number() */
|
int flags; /* flags to number() */
|
||||||
|
@ -309,12 +311,27 @@ int bvsnprintf(char *buf, int size, const char *fmt, va_list args)
|
||||||
|
|
||||||
/* Router/Network ID - essentially IPv4 address in u32 value */
|
/* Router/Network ID - essentially IPv4 address in u32 value */
|
||||||
case 'R':
|
case 'R':
|
||||||
|
if(qualifier == 'l') {
|
||||||
|
X = va_arg(args, u64);
|
||||||
|
bsprintf(ipbuf, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
|
||||||
|
((X >> 56) & 0xff),
|
||||||
|
((X >> 48) & 0xff),
|
||||||
|
((X >> 40) & 0xff),
|
||||||
|
((X >> 32) & 0xff),
|
||||||
|
((X >> 24) & 0xff),
|
||||||
|
((X >> 16) & 0xff),
|
||||||
|
((X >> 8) & 0xff),
|
||||||
|
(X & 0xff));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
x = va_arg(args, u32);
|
x = va_arg(args, u32);
|
||||||
bsprintf(ipbuf, "%d.%d.%d.%d",
|
bsprintf(ipbuf, "%d.%d.%d.%d",
|
||||||
((x >> 24) & 0xff),
|
((x >> 24) & 0xff),
|
||||||
((x >> 16) & 0xff),
|
((x >> 16) & 0xff),
|
||||||
((x >> 8) & 0xff),
|
((x >> 8) & 0xff),
|
||||||
(x & 0xff));
|
(x & 0xff));
|
||||||
|
}
|
||||||
s = ipbuf;
|
s = ipbuf;
|
||||||
goto str;
|
goto str;
|
||||||
|
|
||||||
|
|
|
@ -30,4 +30,6 @@ static inline char *xbasename(const char *str)
|
||||||
return s ? s+1 : (char *) str;
|
return s ? s+1 : (char *) str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define ROUTER_ID_64_LENGTH 23
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -919,6 +919,9 @@ protos_build(void)
|
||||||
proto_build(&proto_bfd);
|
proto_build(&proto_bfd);
|
||||||
bfd_init_all();
|
bfd_init_all();
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_BABEL
|
||||||
|
proto_build(&proto_babel);
|
||||||
|
#endif
|
||||||
|
|
||||||
proto_pool = rp_new(&root_pool, "Protocols");
|
proto_pool = rp_new(&root_pool, "Protocols");
|
||||||
proto_flush_event = ev_new(proto_pool);
|
proto_flush_event = ev_new(proto_pool);
|
||||||
|
|
|
@ -76,7 +76,7 @@ void protos_dump_all(void);
|
||||||
|
|
||||||
extern struct protocol
|
extern struct protocol
|
||||||
proto_device, proto_radv, proto_rip, proto_static,
|
proto_device, proto_radv, proto_rip, proto_static,
|
||||||
proto_ospf, proto_pipe, proto_bgp, proto_bfd;
|
proto_ospf, proto_pipe, proto_bgp, proto_bfd, proto_babel;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Routing Protocol Instance
|
* Routing Protocol Instance
|
||||||
|
|
11
nest/route.h
11
nest/route.h
|
@ -219,6 +219,12 @@ typedef struct rte {
|
||||||
struct {
|
struct {
|
||||||
u8 suppressed; /* Used for deterministic MED comparison */
|
u8 suppressed; /* Used for deterministic MED comparison */
|
||||||
} bgp;
|
} bgp;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_BABEL
|
||||||
|
struct {
|
||||||
|
u16 metric; /* Babel metric */
|
||||||
|
u64 router_id; /* Babel router id */
|
||||||
|
} babel;
|
||||||
#endif
|
#endif
|
||||||
struct { /* Routes generated by krt sync (both temporary and inherited ones) */
|
struct { /* Routes generated by krt sync (both temporary and inherited ones) */
|
||||||
s8 src; /* Alleged route source (see krt.h) */
|
s8 src; /* Alleged route source (see krt.h) */
|
||||||
|
@ -374,6 +380,7 @@ typedef struct rta {
|
||||||
#define RTS_OSPF_EXT2 10 /* OSPF external route type 2 */
|
#define RTS_OSPF_EXT2 10 /* OSPF external route type 2 */
|
||||||
#define RTS_BGP 11 /* BGP route */
|
#define RTS_BGP 11 /* BGP route */
|
||||||
#define RTS_PIPE 12 /* Inter-table wormhole */
|
#define RTS_PIPE 12 /* Inter-table wormhole */
|
||||||
|
#define RTS_BABEL 13 /* Babel route */
|
||||||
|
|
||||||
#define RTC_UNICAST 0
|
#define RTC_UNICAST 0
|
||||||
#define RTC_BROADCAST 1
|
#define RTC_BROADCAST 1
|
||||||
|
@ -422,7 +429,8 @@ typedef struct eattr {
|
||||||
#define EAP_RIP 2 /* RIP */
|
#define EAP_RIP 2 /* RIP */
|
||||||
#define EAP_OSPF 3 /* OSPF */
|
#define EAP_OSPF 3 /* OSPF */
|
||||||
#define EAP_KRT 4 /* Kernel route attributes */
|
#define EAP_KRT 4 /* Kernel route attributes */
|
||||||
#define EAP_MAX 5
|
#define EAP_BABEL 5 /* Babel attributes */
|
||||||
|
#define EAP_MAX 6
|
||||||
|
|
||||||
#define EA_CODE(proto,id) (((proto) << 8) | (id))
|
#define EA_CODE(proto,id) (((proto) << 8) | (id))
|
||||||
#define EA_PROTO(ea) ((ea) >> 8)
|
#define EA_PROTO(ea) ((ea) >> 8)
|
||||||
|
@ -547,6 +555,7 @@ extern struct protocol *attr_class_to_protocol[EAP_MAX];
|
||||||
#define DEF_PREF_DIRECT 240 /* Directly connected */
|
#define DEF_PREF_DIRECT 240 /* Directly connected */
|
||||||
#define DEF_PREF_STATIC 200 /* Static route */
|
#define DEF_PREF_STATIC 200 /* Static route */
|
||||||
#define DEF_PREF_OSPF 150 /* OSPF intra-area, inter-area and type 1 external routes */
|
#define DEF_PREF_OSPF 150 /* OSPF intra-area, inter-area and type 1 external routes */
|
||||||
|
#define DEF_PREF_BABEL 130 /* Babel */
|
||||||
#define DEF_PREF_RIP 120 /* RIP */
|
#define DEF_PREF_RIP 120 /* RIP */
|
||||||
#define DEF_PREF_BGP 100 /* BGP */
|
#define DEF_PREF_BGP 100 /* BGP */
|
||||||
#define DEF_PREF_PIPE 70 /* Routes piped from other tables */
|
#define DEF_PREF_PIPE 70 /* Routes piped from other tables */
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
H Protocols
|
H Protocols
|
||||||
|
C babel
|
||||||
C bfd
|
C bfd
|
||||||
C bgp
|
C bgp
|
||||||
C ospf
|
C ospf
|
||||||
|
|
2
proto/babel/Doc
Normal file
2
proto/babel/Doc
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
S babel.c
|
||||||
|
S packet.c
|
5
proto/babel/Makefile
Normal file
5
proto/babel/Makefile
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
source=babel.c packets.c
|
||||||
|
root-rel=../../
|
||||||
|
dir-name=proto/babel
|
||||||
|
|
||||||
|
include ../../Rules
|
2055
proto/babel/babel.c
Normal file
2055
proto/babel/babel.c
Normal file
File diff suppressed because it is too large
Load diff
335
proto/babel/babel.h
Normal file
335
proto/babel/babel.h
Normal file
|
@ -0,0 +1,335 @@
|
||||||
|
/*
|
||||||
|
* BIRD -- The Babel protocol
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015--2016 Toke Hoiland-Jorgensen
|
||||||
|
*
|
||||||
|
* Can be freely distributed and used under the terms of the GNU GPL.
|
||||||
|
*
|
||||||
|
* This file contains the data structures used by Babel.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _BIRD_BABEL_H_
|
||||||
|
#define _BIRD_BABEL_H_
|
||||||
|
|
||||||
|
#include "nest/bird.h"
|
||||||
|
#include "nest/cli.h"
|
||||||
|
#include "nest/iface.h"
|
||||||
|
#include "nest/route.h"
|
||||||
|
#include "nest/protocol.h"
|
||||||
|
#include "nest/locks.h"
|
||||||
|
#include "lib/resource.h"
|
||||||
|
#include "lib/lists.h"
|
||||||
|
#include "lib/socket.h"
|
||||||
|
#include "lib/string.h"
|
||||||
|
#include "lib/timer.h"
|
||||||
|
|
||||||
|
#ifndef IPV6
|
||||||
|
#error "The Babel protocol only speaks IPv6"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define EA_BABEL_METRIC EA_CODE(EAP_BABEL, 0)
|
||||||
|
#define EA_BABEL_ROUTER_ID EA_CODE(EAP_BABEL, 1)
|
||||||
|
|
||||||
|
#define BABEL_MAGIC 42
|
||||||
|
#define BABEL_VERSION 2
|
||||||
|
#define BABEL_PORT 6696
|
||||||
|
#define BABEL_INFINITY 0xFFFF
|
||||||
|
|
||||||
|
|
||||||
|
#define BABEL_HELLO_INTERVAL_WIRED 4 /* Default hello intervals in seconds */
|
||||||
|
#define BABEL_HELLO_INTERVAL_WIRELESS 4
|
||||||
|
#define BABEL_UPDATE_INTERVAL_FACTOR 4
|
||||||
|
#define BABEL_IHU_INTERVAL_FACTOR 3
|
||||||
|
#define BABEL_IHU_EXPIRY_FACTOR(X) ((X)*3/2) /* 1.5 */
|
||||||
|
#define BABEL_HELLO_EXPIRY_FACTOR(X) ((X)*3/2) /* 1.5 */
|
||||||
|
#define BABEL_ROUTE_EXPIRY_FACTOR(X) ((X)*7/2) /* 3.5 */
|
||||||
|
#define BABEL_ROUTE_REFRESH_INTERVAL 2 /* Seconds before route expiry to send route request */
|
||||||
|
#define BABEL_HOLD_TIME 10 /* Expiry time for our own routes */
|
||||||
|
#define BABEL_RXCOST_WIRED 96
|
||||||
|
#define BABEL_RXCOST_WIRELESS 256
|
||||||
|
#define BABEL_INITIAL_HOP_COUNT 255
|
||||||
|
#define BABEL_MAX_SEND_INTERVAL 5
|
||||||
|
#define BABEL_TIME_UNITS 100 /* On-wire times are counted in centiseconds */
|
||||||
|
|
||||||
|
#define BABEL_SEQNO_REQUEST_EXPIRY 60
|
||||||
|
#define BABEL_GARBAGE_INTERVAL 300
|
||||||
|
|
||||||
|
#define BABEL_OVERHEAD (SIZE_OF_IP_HEADER+UDP_HEADER_LENGTH)
|
||||||
|
#define BABEL_MIN_MTU (512 + BABEL_OVERHEAD)
|
||||||
|
|
||||||
|
|
||||||
|
enum babel_tlv_type {
|
||||||
|
BABEL_TLV_PAD1 = 0,
|
||||||
|
BABEL_TLV_PADN = 1,
|
||||||
|
BABEL_TLV_ACK_REQ = 2,
|
||||||
|
BABEL_TLV_ACK = 3,
|
||||||
|
BABEL_TLV_HELLO = 4,
|
||||||
|
BABEL_TLV_IHU = 5,
|
||||||
|
BABEL_TLV_ROUTER_ID = 6,
|
||||||
|
BABEL_TLV_NEXT_HOP = 7,
|
||||||
|
BABEL_TLV_UPDATE = 8,
|
||||||
|
BABEL_TLV_ROUTE_REQUEST = 9,
|
||||||
|
BABEL_TLV_SEQNO_REQUEST = 10,
|
||||||
|
/* extensions - not implemented
|
||||||
|
BABEL_TLV_TS_PC = 11,
|
||||||
|
BABEL_TLV_HMAC = 12,
|
||||||
|
BABEL_TLV_SS_UPDATE = 13,
|
||||||
|
BABEL_TLV_SS_REQUEST = 14,
|
||||||
|
BABEL_TLV_SS_SEQNO_REQUEST = 15,
|
||||||
|
*/
|
||||||
|
BABEL_TLV_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
enum babel_iface_type {
|
||||||
|
/* In practice, UNDEF and WIRED give equivalent behaviour */
|
||||||
|
BABEL_IFACE_TYPE_UNDEF = 0,
|
||||||
|
BABEL_IFACE_TYPE_WIRED = 1,
|
||||||
|
BABEL_IFACE_TYPE_WIRELESS = 2,
|
||||||
|
BABEL_IFACE_TYPE_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
enum babel_ae_type {
|
||||||
|
BABEL_AE_WILDCARD = 0,
|
||||||
|
BABEL_AE_IP4 = 1,
|
||||||
|
BABEL_AE_IP6 = 2,
|
||||||
|
BABEL_AE_IP6_LL = 3,
|
||||||
|
BABEL_AE_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct babel_config {
|
||||||
|
struct proto_config c;
|
||||||
|
|
||||||
|
list iface_list; /* Patterns configured -- keep it first; see babel_reconfigure why */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct babel_iface_config {
|
||||||
|
struct iface_patt i;
|
||||||
|
|
||||||
|
u16 rxcost;
|
||||||
|
u8 type;
|
||||||
|
u8 check_link;
|
||||||
|
int port;
|
||||||
|
u16 hello_interval;
|
||||||
|
u16 ihu_interval;
|
||||||
|
u16 update_interval;
|
||||||
|
|
||||||
|
u16 rx_buffer; /* RX buffer size, 0 for MTU */
|
||||||
|
u16 tx_length; /* TX packet length limit (including headers), 0 for MTU */
|
||||||
|
int tx_tos;
|
||||||
|
int tx_priority;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct babel_proto {
|
||||||
|
struct proto p;
|
||||||
|
timer *timer;
|
||||||
|
struct fib rtable;
|
||||||
|
list interfaces; /* Interfaces we really know about (struct babel_iface) */
|
||||||
|
u64 router_id;
|
||||||
|
u16 update_seqno; /* To be increased on request */
|
||||||
|
u8 triggered; /* For triggering global updates */
|
||||||
|
|
||||||
|
slab *route_slab;
|
||||||
|
slab *source_slab;
|
||||||
|
slab *msg_slab;
|
||||||
|
|
||||||
|
slab *seqno_slab;
|
||||||
|
list seqno_cache; /* Seqno requests in the cache (struct babel_seqno_request) */
|
||||||
|
|
||||||
|
struct tbf log_pkt_tbf; /* TBF for packet messages */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct babel_iface {
|
||||||
|
node n;
|
||||||
|
|
||||||
|
struct babel_proto *proto;
|
||||||
|
struct iface *iface;
|
||||||
|
|
||||||
|
struct babel_iface_config *cf;
|
||||||
|
|
||||||
|
u8 up;
|
||||||
|
|
||||||
|
pool *pool;
|
||||||
|
char *ifname;
|
||||||
|
sock *sk;
|
||||||
|
ip_addr addr;
|
||||||
|
int tx_length;
|
||||||
|
list neigh_list; /* List of neighbors seen on this iface (struct babel_neighbor) */
|
||||||
|
list msg_queue;
|
||||||
|
|
||||||
|
u16 hello_seqno; /* To be increased on each hello */
|
||||||
|
|
||||||
|
bird_clock_t next_hello;
|
||||||
|
bird_clock_t next_regular;
|
||||||
|
bird_clock_t next_triggered;
|
||||||
|
bird_clock_t want_triggered;
|
||||||
|
|
||||||
|
timer *timer;
|
||||||
|
event *send_event;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct babel_neighbor {
|
||||||
|
node n;
|
||||||
|
struct babel_iface *ifa;
|
||||||
|
|
||||||
|
ip_addr addr;
|
||||||
|
u16 txcost;
|
||||||
|
u8 hello_cnt;
|
||||||
|
u16 hello_map;
|
||||||
|
u16 next_hello_seqno;
|
||||||
|
/* expiry timers */
|
||||||
|
bird_clock_t hello_expiry;
|
||||||
|
bird_clock_t ihu_expiry;
|
||||||
|
|
||||||
|
list routes; /* Routes this neighbour has sent us (struct babel_route) */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct babel_source {
|
||||||
|
node n;
|
||||||
|
|
||||||
|
u64 router_id;
|
||||||
|
u16 seqno;
|
||||||
|
u16 metric;
|
||||||
|
bird_clock_t expires;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct babel_route {
|
||||||
|
node n;
|
||||||
|
node neigh_route;
|
||||||
|
struct babel_entry *e;
|
||||||
|
struct babel_neighbor *neigh;
|
||||||
|
|
||||||
|
u16 seqno;
|
||||||
|
u16 advert_metric;
|
||||||
|
u16 metric;
|
||||||
|
u64 router_id;
|
||||||
|
ip_addr next_hop;
|
||||||
|
bird_clock_t refresh_time;
|
||||||
|
bird_clock_t expires;
|
||||||
|
u16 expiry_interval;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct babel_entry {
|
||||||
|
struct fib_node n;
|
||||||
|
struct babel_proto *proto;
|
||||||
|
struct babel_route *selected_in;
|
||||||
|
struct babel_route *selected_out;
|
||||||
|
|
||||||
|
bird_clock_t updated;
|
||||||
|
|
||||||
|
list sources; /* Source entries for this prefix (struct babel_source). */
|
||||||
|
list routes; /* Routes for this prefix (struct babel_route) */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Stores forwarded seqno requests for duplicate suppression. */
|
||||||
|
struct babel_seqno_request {
|
||||||
|
node n;
|
||||||
|
ip_addr prefix;
|
||||||
|
u8 plen;
|
||||||
|
u64 router_id;
|
||||||
|
u16 seqno;
|
||||||
|
bird_clock_t updated;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Internal TLV messages
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct babel_msg_ack_req {
|
||||||
|
u8 type;
|
||||||
|
u16 nonce;
|
||||||
|
u16 interval;
|
||||||
|
ip_addr sender;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct babel_msg_ack {
|
||||||
|
u8 type;
|
||||||
|
u16 nonce;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct babel_msg_hello {
|
||||||
|
u8 type;
|
||||||
|
u16 seqno;
|
||||||
|
u16 interval;
|
||||||
|
ip_addr sender;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct babel_msg_ihu {
|
||||||
|
u8 type;
|
||||||
|
u8 ae;
|
||||||
|
u16 rxcost;
|
||||||
|
u16 interval;
|
||||||
|
ip_addr addr;
|
||||||
|
ip_addr sender;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct babel_msg_update {
|
||||||
|
u8 type;
|
||||||
|
u8 ae;
|
||||||
|
u8 plen;
|
||||||
|
u16 interval;
|
||||||
|
u16 seqno;
|
||||||
|
u16 metric;
|
||||||
|
ip_addr prefix;
|
||||||
|
u64 router_id;
|
||||||
|
ip_addr next_hop;
|
||||||
|
ip_addr sender;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct babel_msg_route_request {
|
||||||
|
u8 type;
|
||||||
|
u8 full;
|
||||||
|
u8 plen;
|
||||||
|
ip_addr prefix;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct babel_msg_seqno_request {
|
||||||
|
u8 type;
|
||||||
|
u8 plen;
|
||||||
|
u16 seqno;
|
||||||
|
u8 hop_count;
|
||||||
|
u64 router_id;
|
||||||
|
ip_addr prefix;
|
||||||
|
ip_addr sender;
|
||||||
|
};
|
||||||
|
|
||||||
|
union babel_msg {
|
||||||
|
u8 type;
|
||||||
|
struct babel_msg_ack_req ack_req;
|
||||||
|
struct babel_msg_ack ack;
|
||||||
|
struct babel_msg_hello hello;
|
||||||
|
struct babel_msg_ihu ihu;
|
||||||
|
struct babel_msg_update update;
|
||||||
|
struct babel_msg_route_request route_request;
|
||||||
|
struct babel_msg_seqno_request seqno_request;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct babel_msg_node {
|
||||||
|
node n;
|
||||||
|
union babel_msg msg;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* babel.c */
|
||||||
|
void babel_handle_ack_req(union babel_msg *msg, struct babel_iface *ifa);
|
||||||
|
void babel_handle_ack(union babel_msg *msg, struct babel_iface *ifa);
|
||||||
|
void babel_handle_hello(union babel_msg *msg, struct babel_iface *ifa);
|
||||||
|
void babel_handle_ihu(union babel_msg *msg, struct babel_iface *ifa);
|
||||||
|
void babel_handle_router_id(union babel_msg *msg, struct babel_iface *ifa);
|
||||||
|
void babel_handle_update(union babel_msg *msg, struct babel_iface *ifa);
|
||||||
|
void babel_handle_route_request(union babel_msg *msg, struct babel_iface *ifa);
|
||||||
|
void babel_handle_seqno_request(union babel_msg *msg, struct babel_iface *ifa);
|
||||||
|
|
||||||
|
void babel_show_interfaces(struct proto *P, char *iff);
|
||||||
|
void babel_show_neighbors(struct proto *P, char *iff);
|
||||||
|
void babel_show_entries(struct proto *P);
|
||||||
|
|
||||||
|
/* packets.c */
|
||||||
|
void babel_enqueue(union babel_msg *msg, struct babel_iface *ifa);
|
||||||
|
void babel_send_unicast(union babel_msg *msg, struct babel_iface *ifa, ip_addr dest);
|
||||||
|
int babel_open_socket(struct babel_iface *ifa);
|
||||||
|
void babel_send_queue(void *arg);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
129
proto/babel/config.Y
Normal file
129
proto/babel/config.Y
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
/*
|
||||||
|
* BIRD -- Babel Configuration
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015-2016 Toke Hoiland-Jorgensen
|
||||||
|
*
|
||||||
|
* Can be freely distributed and used under the terms of the GNU GPL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CF_HDR
|
||||||
|
|
||||||
|
#include "proto/babel/babel.h"
|
||||||
|
#include "nest/iface.h"
|
||||||
|
|
||||||
|
CF_DEFINES
|
||||||
|
|
||||||
|
#define BABEL_CFG ((struct babel_config *) this_proto)
|
||||||
|
#define BABEL_IFACE ((struct babel_iface_config *) this_ipatt)
|
||||||
|
|
||||||
|
CF_DECLS
|
||||||
|
|
||||||
|
CF_KEYWORDS(BABEL, METRIC, RXCOST, HELLO, UPDATE, INTERVAL, PORT, WIRED,
|
||||||
|
WIRELESS, RX, TX, BUFFER, LENGTH, CHECK, LINK, BABEL_METRIC)
|
||||||
|
|
||||||
|
CF_GRAMMAR
|
||||||
|
|
||||||
|
CF_ADDTO(proto, babel_proto)
|
||||||
|
|
||||||
|
babel_proto_start: proto_start BABEL
|
||||||
|
{
|
||||||
|
this_proto = proto_config_new(&proto_babel, $1);
|
||||||
|
init_list(&BABEL_CFG->iface_list);
|
||||||
|
};
|
||||||
|
|
||||||
|
babel_proto_item:
|
||||||
|
proto_item
|
||||||
|
| INTERFACE babel_iface
|
||||||
|
;
|
||||||
|
|
||||||
|
babel_proto_opts:
|
||||||
|
/* empty */
|
||||||
|
| babel_proto_opts babel_proto_item ';'
|
||||||
|
;
|
||||||
|
|
||||||
|
babel_proto:
|
||||||
|
babel_proto_start proto_name '{' babel_proto_opts '}';
|
||||||
|
|
||||||
|
|
||||||
|
babel_iface_start:
|
||||||
|
{
|
||||||
|
this_ipatt = cfg_allocz(sizeof(struct babel_iface_config));
|
||||||
|
add_tail(&BABEL_CFG->iface_list, NODE this_ipatt);
|
||||||
|
init_list(&this_ipatt->ipn_list);
|
||||||
|
BABEL_IFACE->port = BABEL_PORT;
|
||||||
|
BABEL_IFACE->type = BABEL_IFACE_TYPE_WIRED;
|
||||||
|
BABEL_IFACE->tx_tos = IP_PREC_INTERNET_CONTROL;
|
||||||
|
BABEL_IFACE->tx_priority = sk_priority_control;
|
||||||
|
BABEL_IFACE->check_link = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
babel_iface_finish:
|
||||||
|
{
|
||||||
|
if (BABEL_IFACE->type == BABEL_IFACE_TYPE_WIRELESS)
|
||||||
|
{
|
||||||
|
if (!BABEL_IFACE->hello_interval)
|
||||||
|
BABEL_IFACE->hello_interval = BABEL_HELLO_INTERVAL_WIRELESS;
|
||||||
|
if (!BABEL_IFACE->rxcost)
|
||||||
|
BABEL_IFACE->rxcost = BABEL_RXCOST_WIRELESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!BABEL_IFACE->hello_interval)
|
||||||
|
BABEL_IFACE->hello_interval = BABEL_HELLO_INTERVAL_WIRED;
|
||||||
|
if (!BABEL_IFACE->rxcost)
|
||||||
|
BABEL_IFACE->rxcost = BABEL_RXCOST_WIRED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!BABEL_IFACE->update_interval)
|
||||||
|
BABEL_IFACE->update_interval = BABEL_IFACE->hello_interval*BABEL_UPDATE_INTERVAL_FACTOR;
|
||||||
|
BABEL_IFACE->ihu_interval = BABEL_IFACE->hello_interval*BABEL_IHU_INTERVAL_FACTOR;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
babel_iface_item:
|
||||||
|
| PORT expr { BABEL_IFACE->port = $2; if (($2<1) || ($2>65535)) cf_error("Invalid port number"); }
|
||||||
|
| RXCOST expr { BABEL_IFACE->rxcost = $2; if (($2<1) || ($2>65535)) cf_error("Invalid rxcost"); }
|
||||||
|
| HELLO INTERVAL expr { BABEL_IFACE->hello_interval = $3; if (($3<1) || ($3>65535)) cf_error("Invalid hello interval"); }
|
||||||
|
| UPDATE INTERVAL expr { BABEL_IFACE->update_interval = $3; if (($3<1) || ($3>65535)) cf_error("Invalid hello interval"); }
|
||||||
|
| TYPE WIRED { BABEL_IFACE->type = BABEL_IFACE_TYPE_WIRED; }
|
||||||
|
| TYPE WIRELESS { BABEL_IFACE->type = BABEL_IFACE_TYPE_WIRELESS; }
|
||||||
|
| RX BUFFER expr { BABEL_IFACE->rx_buffer = $3; if (($3<256) || ($3>65535)) cf_error("RX buffer must be in range 256-65535"); }
|
||||||
|
| TX LENGTH expr { BABEL_IFACE->tx_length = $3; if (($3<256) || ($3>65535)) cf_error("TX length must be in range 256-65535"); }
|
||||||
|
| TX tos { BABEL_IFACE->tx_tos = $2; }
|
||||||
|
| TX PRIORITY expr { BABEL_IFACE->tx_priority = $3; }
|
||||||
|
| CHECK LINK bool { BABEL_IFACE->check_link = $3; }
|
||||||
|
;
|
||||||
|
|
||||||
|
babel_iface_opts:
|
||||||
|
/* empty */
|
||||||
|
| babel_iface_opts babel_iface_item ';'
|
||||||
|
;
|
||||||
|
|
||||||
|
babel_iface_opt_list:
|
||||||
|
/* empty */
|
||||||
|
| '{' babel_iface_opts '}'
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
babel_iface:
|
||||||
|
babel_iface_start iface_patt_list_nopx babel_iface_opt_list babel_iface_finish;
|
||||||
|
|
||||||
|
CF_ADDTO(dynamic_attr, BABEL_METRIC { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_BABEL_METRIC); })
|
||||||
|
|
||||||
|
CF_CLI_HELP(SHOW BABEL, ..., [[Show information about Babel protocol]]);
|
||||||
|
|
||||||
|
CF_CLI(SHOW BABEL INTERFACES, optsym opttext, [<name>] [\"<interface>\"], [[Show information about Babel interfaces]])
|
||||||
|
{ babel_show_interfaces(proto_get_named($4, &proto_babel), $5); };
|
||||||
|
|
||||||
|
CF_CLI(SHOW BABEL NEIGHBORS, optsym opttext, [<name>] [\"<interface>\"], [[Show information about Babel neighbors]])
|
||||||
|
{ babel_show_neighbors(proto_get_named($4, &proto_babel), $5); };
|
||||||
|
|
||||||
|
CF_CLI(SHOW BABEL ENTRIES, optsym opttext, [<name>], [[Show information about Babel prefix entries]])
|
||||||
|
{ babel_show_entries(proto_get_named($4, &proto_babel)); };
|
||||||
|
|
||||||
|
CF_CODE
|
||||||
|
|
||||||
|
CF_END
|
1093
proto/babel/packets.c
Normal file
1093
proto/babel/packets.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -43,6 +43,7 @@
|
||||||
#undef CONFIG_BGP
|
#undef CONFIG_BGP
|
||||||
#undef CONFIG_OSPF
|
#undef CONFIG_OSPF
|
||||||
#undef CONFIG_PIPE
|
#undef CONFIG_PIPE
|
||||||
|
#undef CONFIG_BABEL
|
||||||
|
|
||||||
/* We use multithreading */
|
/* We use multithreading */
|
||||||
#undef USE_PTHREADS
|
#undef USE_PTHREADS
|
||||||
|
|
Loading…
Reference in a new issue