Commit 96660260 authored by Ondřej Filip's avatar Ondřej Filip

Merge branch 'int-new' of ssh://gitlab.labs.nic.cz/labs/bird into int-new

parents 44062812 4841804f
Version 2.0.2 (2018-03-xx)
o Source-specific routing support for Linux kernel and Babel
o BGP: New option 'disable after cease'
o Filter: Allow silent filter execution
o Filter: Fixed stack overflow in BGP mask expressions.
o Several bugfixes
Notes:
Syntax prefix:netmask for IPv4 prefixes was dropped. Just use prefix/pxlen.
Version 2.0.1 (2018-01-16)
o Linux MPLS kernel support
o Better handling of channels inherited from templates
......
......@@ -49,6 +49,8 @@ CF_DECLS
struct rtable_config *r;
struct channel_config *cc;
struct f_inst *x;
struct f_dynamic_attr fda;
struct f_static_attr fsa;
struct filter *f;
struct f_tree *e;
struct f_trie *trie;
......@@ -177,10 +179,6 @@ pxlen4:
if ($2 > IP4_MAX_PREFIX_LENGTH) cf_error("Invalid prefix length %u", $2);
$$ = $2;
}
| ':' IP4 {
$$ = ip4_masklen($2);
if ($$ == 255) cf_error("Invalid netmask %I4", $2);
}
;
net_ip4_: IP4 pxlen4
......
/*
* This is an example configuration file
* (for version 1.x.x, obsolete)
*/
# Yes, even shell-like comments work...
# This is a basic configuration file, which contains boilerplate options and
# some basic examples. It allows the BIRD daemon to start but will not cause
# anything else to happen.
#
# Please refer to the BIRD User's Guide documentation, which is also available
# online at http://bird.network.cz/ in HTML format, for more information on
# configuring BIRD and adding routing protocols.
# Configure logging
#log syslog { debug, trace, info, remote, warning, error, auth, fatal, bug };
#log stderr all;
#log "tmp" all;
log syslog all;
# log "/var/log/bird.log" { debug, trace, info, remote, warning, error, auth, fatal, bug };
# Override router ID
#router id 198.51.100.1;
# Set router ID. It is a unique identification of your router, usually one of
# IPv4 addresses of the router. It is recommended to configure it explicitly.
# router id 198.51.100.1;
# You can define your own symbols...
#define xyzzy = (120+10);
#define '1a-a1' = (30+40);
# Turn on global debugging of all protocols (all messages or just selected classes)
# debug protocols all;
# debug protocols { events, states };
# Define a route filter...
#filter test_filter {
# if net ~ 10.0.0.0/16 then accept;
# else reject;
#}
# Turn on internal watchdog
# watchdog warning 5 s;
# watchdog timeout 30 s;
#filter sink { reject; }
#filter okay { accept; }
# You can define your own constants
# define my_asn = 65000;
# define my_addr = 198.51.100.1;
#include "filters.conf";
# Tables master4 and master6 are defined by default
# ipv4 table master4;
# ipv6 table master6;
# Define another routing table
#table testable;
# Define more tables, e.g. for policy routing or as MRIB
# ipv4 table mrib4;
# ipv6 table mrib6;
# Turn on global debugging of all protocols
#debug protocols all;
# The Device protocol is not a real routing protocol. It does not generate any
# routes and it only serves as a module for getting information about network
# interfaces from the kernel. It is necessary in almost any configuration.
protocol device {
}
# Turn on internal watchdog
#watchdog warning 5 s;
#watchdog timeout 30 s;
# The direct protocol automatically generates device routes to
# all network interfaces. Can exist in as many instances as you wish
# if you want to populate multiple routing tables with device routes.
#protocol direct {
# interface "-eth*", "*"; # Restrict network interfaces it works with
#}
# The direct protocol is not a real routing protocol. It automatically generates
# direct routes to all network interfaces. Can exist in as many instances as you
# wish if you want to populate multiple routing tables with direct routes.
protocol direct {
disabled; # Disable by default
ipv4; # Connect to default IPv4 table
ipv6; # ... and to default IPv6 table
}
# This pseudo-protocol performs synchronization between BIRD's routing
# tables and the kernel. If your kernel supports multiple routing tables
# (as Linux 2.2.x does), you can run multiple instances of the kernel
# protocol and synchronize different kernel tables with different BIRD tables.
# The Kernel protocol is not a real routing protocol. Instead of communicating
# with other routers in the network, it performs synchronization of BIRD
# routing tables with the OS kernel. One instance per table.
protocol kernel {
# learn; # Learn all alien routes from the kernel
persist; # Don't remove routes on bird shutdown
scan time 20; # Scan kernel routing table every 20 seconds
# import none; # Default is import all
export all; # Default is export none
# kernel table 5; # Kernel table to synchronize with (default: main)
ipv4 { # Connect protocol to IPv4 table by channel
# table master4; # Default IPv4 table is master4
# import all; # Import to table, default is import all
export all; # Export to protocol. default is export none
};
# learn; # Learn alien routes from the kernel
# kernel table 10; # Kernel table to synchronize with (default: main)
}
# This pseudo-protocol watches all interface up/down events.
protocol device {
scan time 10; # Scan interfaces every 10 seconds
# Another instance for IPv6, skipping default options
protocol kernel {
ipv6 { export all; };
}
# Static routes (again, there can be multiple instances, so that you
# can disable/enable various groups of static routes on the fly).
# Static routes (Again, there can be multiple instances, for different address
# families and to disable/enable various groups of static routes on the fly).
protocol static {
# disabled; # Disable by default
# table testable; # Connect to a non-default table
# preference 1000; # Default preference of routes
# debug { states, routes, filters, interfaces, events, packets };
# debug all;
# route 0.0.0.0/0 via 198.51.100.13;
# route 198.51.100.0/25 unreachable;
ipv4; # Again, IPv4 channel with default options
# route 0.0.0.0/0 via 198.51.100.10;
# route 192.0.2.0/24 blackhole;
# route 10.0.0.0/8 unreachable;
# route 10.1.1.0:255.255.255.0 via 198.51.100.3;
# route 10.1.2.0:255.255.255.0 via 198.51.100.3;
# route 10.1.3.0:255.255.255.0 via 198.51.100.4;
# route 10.2.0.0/24 via "arc0";
# route 10.2.0.0/24 via "eth0";
# # Static routes can be defined with optional attributes
# route 10.1.1.0/24 via 198.51.100.3 { rip_metric = 3; };
# route 10.1.2.0/24 via 198.51.100.3 { ospf_metric1 = 100; };
# route 10.1.3.0/24 via 198.51.100.4 { ospf_metric2 = 100; };
}
# Pipe protocol connects two routing tables... Beware of loops.
#protocol pipe {
# peer table testable;
# Define what routes do we export to this protocol / import from it.
# import all; # default is all
# export all; # default is none
# import none; # If you wish to disable imports
# import filter test_filter; # Use named filter
# import where source = RTS_DEVICE; # Use explicit filter
#}
# RIP aka Rest In Pieces...
#protocol rip MyRIP { # You can also use an explicit name
# preference xyzzy;
# debug all;
# port 1520;
# period 7;
# infinity 16;
# garbage time 60;
# interface "*" { mode broadcast; };
# honor neighbor; # To whom do we agree to send the routing table
# honor always;
# honor never;
# passwords {
# password "nazdar";
# Pipe protocol connects two routing tables. Beware of loops.
# protocol pipe {
# table master4; # No ipv4/ipv6 channel definition like in other protocols
# peer table mrib4;
# import all; # Direction peer table -> table
# export all; # Direction table -> peer table
# }
# RIP example, both RIP and RIPng are supported
# protocol rip {
# ipv4 {
# # Export direct, static routes and ones from RIP itself
# import all;
# export where source ~ [ RTS_DEVICE, RTS_STATIC, RTS_RIP ];
# };
# authentication none;
# import filter { print "importing"; accept; };
# export filter { print "exporting"; accept; };
#}
# interface "eth*" {
# update time 10; # Default period is 30
# timeout time 60; # Default timeout is 180
# authentication cryptographic; # No authentication by default
# password "hello" { algorithm hmac sha256; }; # Default is MD5
# };
# }
#protocol ospf MyOSPF {
# tick 2;
# rfc1583compat yes;
# area 0.0.0.0 {
# stub no;
# OSPF example, both OSPFv2 and OSPFv3 are supported
# protocol ospf v3 {
# ipv6 {
# import all;
# export where source = RTS_STATIC;
# };
# area 0 {
# interface "eth*" {
# hello 9;
# retransmit 6;
# cost 10;
# transmit delay 5;
# dead count 5;
# wait 50;
# type broadcast;
# authentication simple;
# password "pass";
# type broadcast; # Detected by default
# cost 10; # Interface metric
# hello 5; # Default hello perid 10 is too long
# };
# interface "arc0" {
# rx buffer large;
# type nonbroadcast;
# poll 14;
# dead 75;
# neighbors {
# 10.1.1.2 eligible;
# 10.1.1.4;
# };
# strict nonbroadcast yes;
# interface "tun*" {
# type ptp; # PtP mode, avoids DR selection
# cost 100; # Interface metric
# hello 5; # Default hello perid 10 is too long
# };
# interface "xxx0" {
# passwords {
# password "abc" {
# id 1;
# generate to "22-04-2003 11:00:06";
# accept to "17-01-2004 12:01:05";
# };
# password "def" {
# id 2;
# generate from "22-04-2003 11:00:07";
# accept from "17-01-2003 12:01:05";
# };
# };
# authentication cryptographic;
# };
# };
# area 20 {
# stub 1;
# interface "ppp1" {
# hello 8;
# authentication none;
# interface "dummy0" {
# stub; # Stub interface, just propagate it
# };
# interface "fr*";
# virtual link 192.168.0.1 {
# password "sdsdffsdfg";
# authentication cryptographic;
# };
# };
#}
#protocol bgp {
# disabled;
# Define simple filter as an example for BGP import filter
# See https://gitlab.labs.nic.cz/labs/bird/wikis/BGP_filtering for more examples
# filter rt_import
# {
# if bgp_path.first != 64496 then accept;
# if bgp_path.len > 64 then accept;
# if bgp_next_hop != from then accept;
# reject;
# }
# BGP example, explicit name 'uplink1' is used instead of default 'bgp1'
# protocol bgp uplink1 {
# description "My BGP uplink";
# local as 65000;
# neighbor 198.51.100.130 as 64496;
# multihop;
# hold time 240;
# startup hold time 240;
# connect retry time 120;
# keepalive time 80; # defaults to hold time / 3
# start delay time 5; # How long do we wait before initial connect
# error wait time 60, 300;# Minimum and maximum time we wait after an error (when consecutive
# # errors occur, we increase the delay exponentially ...
# error forget time 300; # ... until this timeout expires)
# disable after error; # Disable the protocol automatically when an error occurs
# next hop self; # Disable next hop processing and always advertise our local address as nexthop
# path metric 1; # Prefer routes with shorter paths (like Cisco does)
# default bgp_med 0; # MED value we use for comparison when none is defined
# default bgp_local_pref 0; # The same for local preference
# source address 198.51.100.14; # What local address we use for the TCP connection
# local 198.51.100.1 as 65000;
# neighbor 198.51.100.10 as 64496;
# hold time 90; # Default is 240
# password "secret"; # Password used for MD5 authentication
# rr client; # I am a route reflector and the neighor is my client
# rr cluster id 1.0.0.1; # Use this value for cluster id instead of my router id
# export where source=RTS_STATIC;
# export filter {
# if source = RTS_STATIC then {
# bgp_community = -empty-; bgp_community = add(bgp_community,(65000,5678));
# bgp_origin = 0;
# bgp_community = -empty-; bgp_community.add((65000,5678));
# if (65000,64501) ~ bgp_community then
# bgp_community.add((0, 1));
# if bgp_path ~ [= 65000 =] then
# bgp_path.prepend(65000);
# accept;
# }
# reject;
#
# ipv4 { # regular IPv4 unicast (1/1)
# import filter rt_import;
# export where source ~ [ RTS_STATIC, RTS_BGP ];
# };
#
# ipv6 { # regular IPv6 unicast (2/1)
# import filter rt_import;
# export filter { # The same as 'where' expression above
# if source ~ [ RTS_STATIC, RTS_BGP ]
# then accept;
# else reject;
# };
# };
#
# ipv4 multicast { # IPv4 multicast topology (1/2)
# table mrib4; # explicit IPv4 table
# import filter rt_import;
# export all;
# };
#}
#
# Template usage example
#template bgp rr_client {
# disabled;
# local as 65000;
# multihop;
# ipv6 multicast { # IPv6 multicast topology (2/2)
# table mrib6; # explicit IPv6 table
# import filter rt_import;
# export all;
# };
#}
# Template example. Using templates to define IBGP route reflector clients.
# template bgp rr_clients {
# local 10.0.0.1 as 65000;
# neighbor as 65000;
# rr client;
# rr cluster id 1.0.0.1;
#}
#
#protocol bgp rr_abcd from rr_client {
# neighbor 10.1.4.7 as 65000;
#}
# ipv4 {
# import all;
# export where source = RTS_BGP;
# };
#
# ipv6 {
# import all;
# export where source = RTS_BGP;
# };
# }
#
# protocol bgp client1 from rr_clients {
# neighbor 10.0.1.1;
# }
#
# protocol bgp client2 from rr_clients {
# neighbor 10.0.2.1;
# }
#
# protocol bgp client3 from rr_clients {
# neighbor 10.0.3.1;
# }
......@@ -293,6 +293,20 @@ routes are:
<item>Route next hops (see below)
</itemize>
<sect1>IPv6 source-specific routes
<label id="ip-sadr-routes">
<p>The IPv6 routes containing both destination and source prefix. They are used
for source-specific routing (SSR), also called source-address dependent routing
(SADR), see <rfc id="8043">. Currently limited mostly to the Babel protocol.
Configuration keyword is <cf/ipv6 sadr/.
<itemize>
<item>(PK) Route destination (IP prefix together with its length)
<item>(PK) Route source (IP prefix together with its length)
<item>Route next hops (see below)
</itemize>
<sect1>VPN IPv4 and IPv6 routes
<label id="vpn-routes">
......@@ -646,9 +660,9 @@ agreement").
restricted to interfaces assigned to the VRF and will use sockets bound
to the VRF. Appropriate VRF interface must exist on OS level. For kernel
protocol, an appropriate table still must be explicitly selected by
<cf/table/ option. Note that the VRF support in BIRD and Linux kernel
(4.11) is still in development and is currently problematic outside of
multihop BGP.
<cf/table/ option. Note that for proper VRF support it is necessary to
use Linux kernel version at least 4.14, older versions have limited VRF
implementation.
<tag><label id="proto-channel"><m/channel name/ [{<m/channel config/}]</tag>
Every channel must be explicitly stated. See the protocol-specific
......@@ -1234,12 +1248,17 @@ foot).
operator <cf/.type/. The type may be:
<cf/NET_IP4/ and <cf/NET_IP6/ prefixes hold an IP prefix. The literals
are written as <cf><m/ipaddress//<m/pxlen/</cf>,
or <cf><m>ipaddress</m>/<m>netmask</m></cf>. There are two special
are written as <cf><m/ipaddress//<m/pxlen/</cf>. There are two special
operators on these: <cf/.ip/ which extracts the IP address from the
pair, and <cf/.len/, which separates prefix length from the pair.
So <cf>1.2.0.0/16.len = 16</cf> is true.
<cf/NET_IP6_SADR/ nettype holds both destination and source IPv6
prefix. The literals are written as <cf><m/ipaddress//<m/pxlen/ from
<m/ipaddress//<m/pxlen/</cf>, where the first part is the destination
prefix and the second art is the source prefix. They support the same
operators as IP prefixes, but just for the destination part.
<cf/NET_VPN4/ and <cf/NET_VPN6/ prefixes hold an IP prefix with VPN
Route Distinguisher (<rfc id="4364">). They support the same special
operators as IP prefixes, and also <cf/.rd/ which extracts the Route
......@@ -1460,6 +1479,7 @@ foot).
lclists, with LCs instead of pairs as arguments.
</descrip>
<sect>Operators
<label id="operators">
......@@ -1652,19 +1672,25 @@ cases desirable.
routes over the same IPv6 transport. For sending and receiving Babel packets,
only a link-local IPv6 address is needed.
<p>BIRD does not implement any Babel extensions, but will coexist with
implementations using extensions (and will just ignore extension messages).
<p>BIRD implements an extension for IPv6 source-specific routing (SSR or SADR),
but must be configured accordingly to use it. SADR-enabled Babel router can
interoperate with non-SADR Babel router, but the later would ignore routes
with specific (non-zero) source prefix.
<sect1>Configuration
<label id="babel-config">
<p>Babel supports no global configuration options apart from those common to all
other protocols, but supports the following per-interface configuration options:
<p>The Babel protocol support both IPv4 and IPv6 channels; both can be
configured simultaneously. It can also be configured with <ref
id="ip-sadr-routes" name="IPv6 SADR"> channel instead of regular IPv6
channel, in such case SADR support is enabled. 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>] {
ipv4 { <channel config> };
ipv6 { <channel config> };
ipv6 [sadr] { <channel config> };
interface <interface pattern> {
type <wired|wireless>;
rxcost <number>;
......@@ -1684,8 +1710,8 @@ protocol babel [<name>] {
</code>
<descrip>
<tag><label id="babel-channel">ipv4|ipv6 <m/channel config/</tag>
The supported channels are IPv4 and IPv6.
<tag><label id="babel-channel">ipv4 | ipv6 [sadr] <m/channel config/</tag>
The supported channels are IPv4, IPv6, and IPv6 SADR.
<tag><label id="babel-type">type wired|wireless </tag>
This option specifies the interface type: Wired or wireless. On wired
......@@ -2119,22 +2145,24 @@ to set routing policy and all the other parameters differently for each neighbor
using the following configuration parameters:
<descrip>
<tag><label id="bgp-local">local [<m/ip/] as <m/number/</tag>
<tag><label id="bgp-local">local [<m/ip/] [port <m/number/] [as <m/number/]</tag>
Define which AS we are part of. (Note that contrary to other IP routers,
BIRD is able to act as a router located in multiple AS'es simultaneously,
but in such cases you need to tweak the BGP paths manually in the filters
to get consistent behavior.) Optional <cf/ip/ argument specifies a source
address, equivalent to the <cf/source address/ option (see below). This
parameter is mandatory.
address, equivalent to the <cf/source address/ option (see below).
Optional <cf/port/ argument specifies the local BGP port instead of
standard port 179. The parameter may be used multiple times with
different sub-options (e.g., both <cf/local 10.0.0.1 as 65000;/ and
<cf/local 10.0.0.1; local as 65000;/ are valid). This parameter is
mandatory.
<tag><label id="bgp-neighbor">neighbor [<m/ip/] [port <m/number/] [as <m/number/]</tag>
Define neighboring router this instance will be talking to and what AS
it is located in. In case the neighbor is in the same AS as we are, we
automatically switch to iBGP. Optionally, the remote port may also be
specified. The parameter may be used multiple times with different
sub-options (e.g., both <cf/neighbor 10.0.0.1 as 65000;/ and
<cf/neighbor 10.0.0.1; neighbor as 65000;/ are valid). This parameter is
mandatory.
specified. Like <cf/local/ parameter, this parameter may also be used
multiple times with different sub-options. This parameter is mandatory.
<tag><label id="bgp-iface">interface <m/string/</tag>
Define interface we should use for link-local BGP IPv6 sessions.
......@@ -2744,16 +2772,17 @@ protocol device {
<p>The Direct protocol is a simple generator of device routes for all the
directly connected networks according to the list of interfaces provided by the
kernel via the Device protocol. The Direct protocol supports both IPv4 and IPv6
channels.
channels; both can be configured simultaneously. It can also be configured with
<ref id="ip-sadr-routes" name="IPv6 SADR"> channel instead of regular IPv6
channel in order to be used together with SADR-enabled Babel protocol.
<p>The question is whether it is a good idea to have such device routes in BIRD
routing table. OS kernel usually handles device routes for directly connected
networks by itself so we don't need (and don't want) to export these routes to
the kernel protocol. OSPF protocol creates device routes for its interfaces
itself and BGP protocol is usually used for exporting aggregate routes. Although
there are some use cases that use the direct protocol (like abusing eBGP as an
IGP routing protocol), in most cases it is not needed to have these device
routes in BIRD routing table and to use the direct protocol.
itself and BGP protocol is usually used for exporting aggregate routes. But the
Direct protocol is necessary for distance-vector protocols like RIP or Babel to
announce local networks.
<p>There is one notable case when you definitely want to use the direct protocol
-- running BIRD on BSD systems. Having high priority device routes for directly
......@@ -2828,8 +2857,10 @@ kernel protocols to the same routing table and changing route destination
(gateway) in an export filter of a kernel protocol does not work. Both
limitations can be overcome using another routing table and the pipe protocol.
<p>The Kernel protocol supports both IPv4 and IPv6 channels; only one of them
can be configured in each protocol instance.
<p>The Kernel protocol supports both IPv4 and IPv6 channels; only one channel
can be configured in each protocol instance. On Linux, it also supports <ref
id="ip-sadr-routes" name="IPv6 SADR"> and <ref id="mpls-routes" name="MPLS">
channels.
<sect1>Configuration
<label id="krt-config">
......@@ -4280,6 +4311,7 @@ protocol rip {
<sect>RPKI
<label id="rpki">
<sect1>Introduction
......
This diff is collapsed.
......@@ -2,6 +2,7 @@
* Filters: utility functions
*
* Copyright 1998 Pavel Machek <pavel@ucw.cz>
* 2017 Jan Maria Matejka <mq@ucw.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
......@@ -13,43 +14,48 @@
#define P(a,b) ((a<<8) | b)
struct f_inst *
f_new_inst(void)
f_new_inst(enum f_instruction_code fi_code)
{
struct f_inst * ret;
ret = cfg_alloc(sizeof(struct f_inst));
ret->code = ret->aux = 0;
ret->arg1 = ret->arg2 = ret->next = NULL;
ret = cfg_allocz(sizeof(struct f_inst));
ret->fi_code = fi_code;
ret->lineno = ifs->lino;
return ret;
}
struct f_inst *
f_new_dynamic_attr(int type, int f_type, int code)
f_new_inst_da(enum f_instruction_code fi_code, struct f_dynamic_attr da)
{
/* FIXME: Remove the f_type parameter? */
struct f_inst *f = f_new_inst();
f->aux = (f_type << 8) | type;
f->a2.i = code;
return f;
struct f_inst *ret = f_new_inst(fi_code);
ret->aux = (da.f_type << 8) | da.type;
ret->a2.i = da.ea_code;
return ret;
}
struct f_inst *
f_new_inst_sa(enum f_instruction_code fi_code, struct f_static_attr sa)
{
struct f_inst *ret = f_new_inst(fi_code);
ret->aux = sa.f_type;
ret->a2.i = sa.sa_code;
ret->a1.i = sa.readonly;
return ret;
}