From cec4a73ccb22ed412e87560e4210b6df40832aad Mon Sep 17 00:00:00 2001 From: "Ondrej Zajicek (work)" Date: Tue, 4 Oct 2016 00:31:43 +0200 Subject: Doc: Documentation for large communities --- doc/bird.sgml | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) (limited to 'doc') diff --git a/doc/bird.sgml b/doc/bird.sgml index 26673f03..bb88dc61 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -1048,7 +1048,16 @@ foot). for int set look like [ 1, 2, 5..7 ]. As you can see, both simple @@ -1067,9 +1076,15 @@ foot). (like define one=1; @@ -1205,6 +1220,13 @@ foot). The same operations (like @@ -2193,6 +2215,14 @@ some of them (marked with `lclist + List of large community values associated with the route. Large BGP + communities is another variant of communities, but contrary to extended + communities they behave very much the same way as regular communities, + just larger -- they are uniform untyped triplets of 32bit numbers. + Individual community values are represented using an quad This attribute is created by the route reflector when reflecting the route and contains the router ID of the originator of the route in the -- cgit v1.2.3 From 9faf72c8cc9a099b41c90ee1822e8bca22fd0596 Mon Sep 17 00:00:00 2001 From: Pavel Tvrdik Date: Thu, 29 Sep 2016 11:20:04 +0200 Subject: Doc: Fix whitespaces --- doc/sbase/dist/birddoc/groff/mapping | 144 ++++++++++++++++----------------- doc/sbase/dist/birddoc/html/mapping | 60 +++++++------- doc/sbase/dist/birddoc/latex2e/mapping | 42 +++++----- doc/sbase/dtd/birddoc.dtd | 102 +++++++++++------------ 4 files changed, 174 insertions(+), 174 deletions(-) (limited to 'doc') diff --git a/doc/sbase/dist/birddoc/groff/mapping b/doc/sbase/dist/birddoc/groff/mapping index 71d2c935..3861a28d 100644 --- a/doc/sbase/dist/birddoc/groff/mapping +++ b/doc/sbase/dist/birddoc/groff/mapping @@ -6,7 +6,7 @@ % Based on qwertz replacement file by Tom Gordon % linuxdoc mods by mdw -% Groff dependencies are few. To port to another roff: +% Groff dependencies are few. To port to another roff: % 1. Check and modify, if necessary, font changes. (e.g. In psroff the % same fonts have other names.) % 2. Check the code for including Encapsulated PostScript, generated @@ -19,13 +19,13 @@ % Hacked by mdw ".nr PI 3n\n" - ".ds CF \\\\n\%\n" + ".ds CF \\\\n\%\n" ".ds CH \\&\n" ".ds dR $\n" % dollar, to avoid EQN conflicts % Start with no TOC ".ds printtoc\n" - + % Footnote style ".nr FF 1\n" @@ -51,16 +51,16 @@ ".nr HM 0i\n" ".nr FM 0i\n" - % Turn off right-margin filling + % Turn off right-margin filling ".na\n" - + % h is 1 if first paragraph after heading - ".nr h 0\n" + ".nr h 0\n" % initialize heading level - - ".nr il 1\n" + + ".nr il 1\n" % Number registers for list @@ -68,20 +68,20 @@ ".nr ll 0\n" % list level, stores current level ".nr el 0\n" % current enumeration level - % Not all list levels are enumerations, as + % Not all list levels are enumerations, as % itemizations can be embedded within enumerations % and vice versa - + % type of list level is in \n(t\n(ll, where % 0 : itemize, 1 : enumerate, 2: description % enumerator for an enumeration level is in % \n(e\n(el -- i.e. \n(e1=2 means current item of % enumeration level 1 is 2 - + % context-sensitive paragraph macro -% Bug: There's some problem using this to re-start paragraphs after the +% Bug: There's some problem using this to re-start paragraphs after the % and , so after verb and code I insert .LP. That's fine % except that is loses indentation when using verb or code inside of a list. @@ -95,21 +95,21 @@ % for this enumeration level ".if \\\\n(t\\\\n(ll=1 \\{.IP \\\\n+(e\\\\n(el.\\}\n" % if first par element of descrip, do nothing -".\\}\n" +".\\}\n" ".el .sp \n" % subsequent par element of item ".\\}\n" ".el \\{\\\n" % not within list -".ie \\\\nh=1 \\{\\\n" % first par after heading -".LP\n" +".ie \\\\nh=1 \\{\\\n" % first par after heading +".LP\n" ".nr h 0\n" % reset h flag -".\\}\n" +".\\}\n" ".el .LP \n" % Changed from .PP, mdw ".\\}\n" ".nh\n" -"..\n" +"..\n" + + - - % for each level, a number register is created % to store its type and current item number, where % -1=bullet of an itemized list. @@ -141,7 +141,7 @@ % set initial level of headings, in register il
+ ".nr il 0" + -
+ ".if '\\*[printtoc]'true' .PX\n" + + ".if '\\*[printtoc]'true' .PX\n" + ".nr il 1" + + ".bp\n" @@ -153,23 +153,23 @@ ".bp\n" ".TC" + - + + ".nr il -1" + - + % Hacked up titlepag stuff to look more reasonable. Titles and author % names are now stored in strings, printed by the end of . -% Wake up! This uses groff-like long string names. You must use groff +% Wake up! This uses groff-like long string names. You must use groff % to format this. + ".ds mdwtitle\n" ".ds mdwsubtitle\n" - ".ds mdwdate\n" + ".ds mdwdate\n" ".de printabstract\n" "..\n" + + "\\*[mdwtitle]\n" @@ -181,10 +181,10 @@ "\\*[mdwdate]\n" ".br\n" ".printabstract\n" - ".br\n" + ".br\n" % + ".TL" + -% +% + ".ds mdwtitle " + @@ -194,13 +194,13 @@ % ".SM" + % + ".LG" + - + ".ds mdwsubtitle " + + ".ds mdwsubtitle " + - + ".ds mdwdate " + + ".ds mdwdate " + - + ".de printabstract\n" + + ".de printabstract\n" ".LP\n" + ".." + @@ -215,10 +215,10 @@ + ".br" + - + - "\\**\n" + "\\**\n" ".FS" + + ".FE" + @@ -229,11 +229,11 @@ + ".br" - + -
-
+
+
+ ".EH '" "'''" + @@ -263,13 +263,13 @@ - + - + - + ".bp\n" + + ".bp\n" ".NH \\n(il " + @@ -283,7 +283,7 @@ + ".NH 4+\\n(il" + - + + ".NH 5+\\n(il" + @@ -292,10 +292,10 @@ + "\\*h\n" ".XS \\n%\n" "\\*(SN \\*h\n" - ".XE\n" + ".XE\n" ".nr h 1\n" % set heading flag to true -

+ ".Pp" + +

+ ".Pp" +

+ ".nr ll +1\n" % increment list level @@ -309,9 +309,9 @@ ".af e\\n(el \\*(f\\n(el\n" % style of enumerator ".if \\n(ll>1 .RS" + + ".if \\n(ll>1 .RE\n" - ".br\n" + ".br\n" ".nr el -1\n" % decrement enumeration level - ".nr ll -1\n" % decrement list level + ".nr ll -1\n" % decrement list level + ".RS\n" ".nr ll +1\n" % increment list level @@ -324,7 +324,7 @@ % If bi=1 then the paragraph is the first one of the item. + ".nr bi 1\n.Pp" + - + + ".IP \"\\fB" "\\fR\"\n" @@ -337,12 +337,12 @@
"" + ".\[\n[ID]\n.\]" + - + + ".\[\n[ID]\n.\]\n([NOTE])" - " (-- " + " (-- " "--)" + "\\*Q" @@ -353,20 +353,20 @@ + ".nr LL \\n(LL+\\n(PI\n" ".RE" + - "\\fI" - "\\fP" + "\\fI" + "\\fP" - "\\fB" - "\\fR" + "\\fB" + "\\fR" - "\\fI" - "\\fR" + "\\fI" + "\\fR" - "\\fR" - "\\fR" + "\\fR" + "\\fR" - "\\fI" - "\\fR" + "\\fI" + "\\fR" % Changed by mdw "\\fC" @@ -394,10 +394,10 @@ "??" - + - + + ".\[\n" @@ -423,7 +423,7 @@ % ".Pp" + % continue previous paragraph (changed mdw) ".LP" -% tscreen added by mdw +% tscreen added by mdw + ".br\n" ".po 0.75i\n" ".ll 6.0i\n" @@ -487,8 +487,8 @@ % mathematics -- this nroff version needs work. - - + + + ".DS L" + + ".DE" + @@ -496,8 +496,8 @@ + ".DS L" + + ".DE" + - - + + "{" "} over " @@ -505,7 +505,7 @@ "{" "}" - + @@ -527,7 +527,7 @@ " sum " - + % limitation: eqn only does square roots! @@ -539,7 +539,7 @@ "[ca]." + + ".TE" + - "\n" + "\n" "|" @@ -567,8 +567,8 @@ % limitation: no calligraphic characters, using helvetica italics instead. Is there a better font? - "\\fI" - "\\fP" + "\\fI" + "\\fP" " roman }" "}" @@ -584,12 +584,12 @@ + ".if t .PSPIC [file].ps\n" ".if n .sp 4" + - - + + % Are TeX units properly handled by this translation of ph? + ".sp [VSPACE]" + - + + ".sp\n.ce" + @@ -619,7 +619,7 @@ + ".nr PS 18" + - + + ".bp\n\\&" + % letters -- replacement for email, using mh format. diff --git a/doc/sbase/dist/birddoc/html/mapping b/doc/sbase/dist/birddoc/html/mapping index 353d7774..d95b1759 100644 --- a/doc/sbase/dist/birddoc/html/mapping +++ b/doc/sbase/dist/birddoc/html/mapping @@ -21,7 +21,7 @@ + "<@@enddoc>" + % Manual Pages are expected to be formatted using nroff (or groff), unless -% they are included as sections of other qwertz documents. +% they are included as sections of other qwertz documents. @@ -35,7 +35,7 @@ + "<@@title>" - + "

" + + "

" "

" + @@ -48,26 +48,26 @@ + "Thanks " - + + "

" "

" + "
" - +
+
+ "\\markboth"
@@ -110,7 +110,7 @@ "{" "}\n\n" -

+

"\\phantomsection{}"

"\n\n" + "\\begin{itemize}" + @@ -128,7 +128,7 @@ + "\\item " - + "\\item\[{\\ttfamily " + + "\\phantomsection\\item\[{\\ttfamily " "}\] \\hfil\\break\n" + + "\\item\[ " @@ -224,17 +224,17 @@ "\\cparam{" "}" - "\\ref{[ID]} {([NAME])}" + "\\hyperref\[[ID]\]{[NAME]} (p.\\,\\getpagerefnumber{[ID]})" "\\pageref{[ID]}" %url added by HG - "\\nameurl{[URL]}{[NAME]}" + "\\href{[URL]}{[NAME]}" - "\\onlynameurl{[NAME]}" + "\\href{[URL]}{[NAME]}" diff --git a/doc/sbase/dtd/birddoc.dtd b/doc/sbase/dtd/birddoc.dtd index 1654b0e5..6db5066a 100644 --- a/doc/sbase/dtd/birddoc.dtd +++ b/doc/sbase/dtd/birddoc.dtd @@ -564,9 +564,9 @@ anywhere else. - + - + -- cgit v1.2.3 From 22558357d45c27583156f8c11412e37ce48a42e0 Mon Sep 17 00:00:00 2001 From: Pavel Tvrdik Date: Mon, 3 Oct 2016 10:22:24 +0200 Subject: Doc: Add command-line options --version, --help --- doc/bird.sgml | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'doc') diff --git a/doc/bird.sgml b/doc/bird.sgml index f2001e75..5cc12b28 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -181,6 +181,12 @@ BIRD executable by configuring out routing protocols you don't use, and apply graceful restart recovery after start. + + + display bird version. + + + display command-line options to bird.

BIRD writes messages about its work to log files or syslog (according to config). -- cgit v1.2.3 From f5952c7343841fe4b7b63b7a56e95aba104f2e82 Mon Sep 17 00:00:00 2001 From: Pavel Tvrdik Date: Mon, 3 Oct 2016 10:32:28 +0200 Subject: Doc: Daemon command-line options alphabet order --- doc/bird.sgml | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'doc') diff --git a/doc/bird.sgml b/doc/bird.sgml index 5cc12b28..68851e3a 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -154,39 +154,39 @@ BIRD executable by configuring out routing protocols you don't use, and

BIRD writes messages about its work to log files or syslog (according to config). -- cgit v1.2.3 From f15dc6813870565d01378265ab20e017757af220 Mon Sep 17 00:00:00 2001 From: Pavel Tvrdik Date: Mon, 3 Oct 2016 10:59:43 +0200 Subject: Doc: Enable break lines in --- doc/sbase/dist/birddoc/latex2e/mapping | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'doc') diff --git a/doc/sbase/dist/birddoc/latex2e/mapping b/doc/sbase/dist/birddoc/latex2e/mapping index 9b8962d8..161227d2 100644 --- a/doc/sbase/dist/birddoc/latex2e/mapping +++ b/doc/sbase/dist/birddoc/latex2e/mapping @@ -4,6 +4,7 @@ % The \relax is there to avoid sgml2latex rewriting the class + "\\relax\\documentclass\[a4paper,10pt,openany\]{book}\n" "\\usepackage\[colorlinks=true,linkcolor=blue,pdftitle={BIRD User's Guide}\]{hyperref}\n" + "\\usepackage{enumitem}\n" "\\usepackage{birddoc}\n" "\\usepackage{qwertz}\n" "\\usepackage{url}\n" @@ -122,7 +123,7 @@ + "\\begin{list}{}{}\n" + + "\\end{list}" + - + "\\begin{description}" + + + "\\begin{description}\[style=unboxed\]" + + "\\end{description}" + + "\\item " -- cgit v1.2.3 From 74d76f6c3877e4a745fb63b55486810322076153 Mon Sep 17 00:00:00 2001 From: Pavel Tvrdik Date: Mon, 3 Oct 2016 11:36:44 +0200 Subject: Doc: Fix unnecessary special chars --- doc/bird.sgml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'doc') diff --git a/doc/bird.sgml b/doc/bird.sgml index 68851e3a..591bb87a 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -815,7 +815,7 @@ This argument can be omitted if there exists only a single instance. number of networks, number of routes before and after filtering). If you use

" "
" + diff --git a/doc/sbase/dist/birddoc/latex2e/mapping b/doc/sbase/dist/birddoc/latex2e/mapping index 7653cb78..e7c62e0a 100644 --- a/doc/sbase/dist/birddoc/latex2e/mapping +++ b/doc/sbase/dist/birddoc/latex2e/mapping @@ -156,7 +156,7 @@ % The idea here is to automatically insert soft hyphens after every slash in % the filename, so long filenames will break naturally. The url{} macro is % a kluge but it works, - "\\url{" + "{\\tt " "}" "\\footnote{" -- cgit v1.2.3 From 9c20a8b7ae69487397392c720a5e75087c343df1 Mon Sep 17 00:00:00 2001 From: Pavel Tvrdik Date: Mon, 3 Oct 2016 12:35:36 +0200 Subject: Doc: Fix inline Don't make space before or after link name. --- doc/sbase/dist/birddoc/html/mapping | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'doc') diff --git a/doc/sbase/dist/birddoc/html/mapping b/doc/sbase/dist/birddoc/html/mapping index 6d080738..5ce36066 100644 --- a/doc/sbase/dist/birddoc/html/mapping +++ b/doc/sbase/dist/birddoc/html/mapping @@ -202,9 +202,7 @@ "<@@endurl>" +
- + "<@@url>[URL]\n" - "[NAME]\n" - "<@@endurl>" + + "[NAME]" % ref modified to have an optional name field -- cgit v1.2.3 From 7935b9d21228dcd1eb95ebcb056b2a815e3e854b Mon Sep 17 00:00:00 2001 From: Pavel Tvrdik Date: Thu, 29 Sep 2016 18:08:40 +0200 Subject: Doc: Add tag for links to RFCs --- doc/bird.sgml | 238 +++++++++++++++------------------ doc/sbase/dist/birddoc/html/mapping | 4 + doc/sbase/dist/birddoc/latex2e/mapping | 3 + doc/sbase/dtd/birddoc.dtd | 6 +- 4 files changed, 118 insertions(+), 133 deletions(-) (limited to 'doc') diff --git a/doc/bird.sgml b/doc/bird.sgml index 159cac46..24be3de0 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -73,8 +73,8 @@ running on background which does the dynamic part of Internet routing, that is it communicates with the other routers, calculates routing tables and sends them to the OS kernel which does the actual packet forwarding. There already exist other such routing daemons: routed (RIP only), GateD (non-free), -Zebra and -MRTD , + and +, but their capabilities are limited and they are relatively hard to configure and maintain. @@ -485,9 +485,9 @@ protocol rip { used to validate route origination of BGP routes. A ROA table contains ROA entries, each consist of a network prefix, a max prefix length and an AS number. A ROA entry specifies prefixes which could be originated - by that AS number. ROA tables could be filled with data from RPKI (RFC - 6480) or from public databases like Whois. ROA tables are examined by - ) or from public databases like Whois. ROA tables are + examined by roa , which can be used to populate the ROA table with static @@ -1270,9 +1270,9 @@ clist) or on clist and pair/quad set (returning true if there is an element of the clist that is also a member of the pair/quad set).

There is one operator related to ROA infrastructure - roa_check(, which checks -current route (which should be from BGP to have AS_PATH argument) in the +examines a ROA table and does route origin validation for a +given network prefix. The basic usage is roa_check(, which +checks current route (which should be from BGP to have AS_PATH argument) in the specified ROA table and returns ROA_UNKNOWN if there is no relevant ROA, ROA_VALID if there is a matching ROA, or ROA_INVALID if there are some relevant ROAs but none of them match. There is also an extended variant @@ -1434,11 +1434,12 @@ corresponding protocol sections. Introduction

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. +

The Babel protocol +() 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.

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 @@ -1580,14 +1581,10 @@ addresses and associated interfaces. When a session changes its state, these protocols are notified and act accordingly (e.g. break an OSPF adjacency when the BFD session went down). -

BIRD implements basic BFD behavior as defined in -RFC 5880 -(some advanced features like the echo mode or authentication are not implemented), -IP transport for BFD as defined in -RFC 5881 and -RFC 5883 -and interaction with client protocols as defined in -RFC 5882. +

BIRD implements basic BFD behavior as defined in (some +advanced features like the echo mode or authentication are not implemented), IP +transport for BFD as defined in and and +interaction with client protocols as defined in .

Note that BFD implementation in BIRD is currently a new feature in development, expect some rough edges and possible UI and configuration changes @@ -1764,31 +1761,16 @@ the packet will travel through if it uses the particular route) in order to avoid routing loops.

BIRD supports all requirements of the BGP4 standard as defined in -RFC 4271 -It also supports the community attributes -(RFC 1997), -capability negotiation -(RFC 5492), -MD5 password authentication -(RFC 2385), -extended communities -(RFC 4360), -route reflectors -(RFC 4456), -graceful restart -(RFC 4724), -multiprotocol extensions -(RFC 4760), -4B AS numbers -(RFC 4893), -and 4B AS numbers in extended communities -(RFC 5668). + It also supports the community attributes (), +capability negotiation (), MD5 password authentication (), extended communities (), route reflectors (), graceful restart (), multiprotocol extensions +(), 4B AS numbers (), and 4B AS numbers in +extended communities (). For IPv6, it uses the standard multiprotocol extensions defined in -RFC 4760 -and applied to IPv6 according to -RFC 2545. + and applied to IPv6 according to . Route selection rules

Open Shortest Path First (OSPF) is a quite complex interior gateway -protocol. The current IPv4 version (OSPFv2) is defined in RFC 2328 - -and the current IPv6 version (OSPFv3) is defined in RFC 5340 - -It's a link state (a.k.a. shortest path first) protocol -- each router maintains -a database describing the autonomous system's topology. Each participating -router has an identical copy of the database and all routers run the same -algorithm calculating a shortest path tree with themselves as a root. OSPF -chooses the least cost path as the best path. +protocol. The current IPv4 version (OSPFv2) is defined in and +the current IPv6 version (OSPFv3) is defined in It's a link +state (a.k.a. shortest path first) protocol -- each router maintains a database +describing the autonomous system's topology. Each participating router has an +identical copy of the database and all routers run the same algorithm +calculating a shortest path tree with themselves as a root. OSPF chooses the +least cost path as the best path.

In OSPF, the autonomous system can be split to several areas in order to reduce the amount of resources consumed for exchanging the routing information @@ -2708,8 +2689,7 @@ protocol ospf <name> { This option controls compatibility of routing table calculation with - RFC 1583 . - Default value is no. + . Default value is no.

BIRD supports RIPv1 -(RFC 1058), -RIPv2 (RFC 2453), -RIPng (RFC 2080), -and RIP cryptographic authentication (SHA-1 not implemented) -(RFC 4822). +

BIRD supports RIPv1 (), RIPv2 (), RIPng (), and RIP cryptographic authentication (SHA-1 not implemented) +().

RIP is a very simple protocol, and it has a lot of shortcomings. Slow convergence, big network load and inability to handle larger networks makes it @@ -3707,8 +3680,9 @@ protocol rip [<name>] { compatibility with neighbors regardless of whether they use ttl security. - For RIPng, TTL security is a standard behavior (required by RFC 2080) - and therefore default value is yes. For IPv4 RIP, default value is no. + For RIPng, TTL security is a standard behavior (required by ) and therefore default value is yes. For IPv4 RIP, default + value is no.

There are several options that give sense only with certain protocols: - -

There are just few configuration options for the Direct protocol:

-

BIRD supports RIPv1 (), RIPv2 (), RIPng (), and RIP cryptographic authentication (SHA-1 not implemented) -(). +id="2080">), and RIP cryptographic authentication ().

RIP is a very simple protocol, and it has a lot of shortcomings. Slow convergence, big network load and inability to handle larger networks makes it @@ -3545,6 +3575,9 @@ protocol rip [<name>] { generate to "<date>"; accept from "<date>"; accept to "<date>"; + from "<date>"; + to "<date>"; + algorithm ( keyed md5 | keyed sha1 | hmac sha1 | hmac sha256 | hmac sha384 | hmac sha512 ); }; }; } @@ -3658,7 +3691,9 @@ protocol rip [<name>] { Selects authentication method to be used. password section. Default: none. @@ -3704,8 +3739,8 @@ protocol rip [<name>] { 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: - no. + hardware drivers or platforms do not implement this feature. + Default: no. Attributes @@ -3737,8 +3772,9 @@ protocol rip { period 12; garbage time 60; interface "eth0" { metric 3; mode multicast; }; - interface "eth*" { metric 2; mode broadcast; }; - authentication none; + interface "eth*" { metric 2; mode broadcast; }; + authentication cryptographic; + password "secret-shared-key" { algorithm hmac sha256; }; import filter { print "importing"; accept; }; export filter { print "exporting"; accept; }; } -- cgit v1.2.3 From e03dc6a984555e3c943735d50376cada2220bac8 Mon Sep 17 00:00:00 2001 From: "Ondrej Zajicek (work)" Date: Sun, 30 Oct 2016 23:51:23 +0100 Subject: BFD: Authentication Implement BFD authentication (part of RFC 5880). Supports plaintext passwords and cryptographic MD5 / SHA-1 authentication. Based on former commit from Pavel Tvrdik --- doc/bird.sgml | 41 ++++++++- proto/bfd/bfd.c | 2 + proto/bfd/bfd.h | 19 +++- proto/bfd/config.Y | 46 ++++++++-- proto/bfd/packets.c | 245 +++++++++++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 333 insertions(+), 20 deletions(-) (limited to 'doc') diff --git a/doc/bird.sgml b/doc/bird.sgml index 7c34c208..6af0e0f6 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -672,7 +672,7 @@ agreement"). authentication is enabled, authentication can be enabled by separate, protocol-dependent authentication none + No passwords are sent in BFD packets. This is the default value. + + authentication simple + Every packet carries 16 bytes of password. Received packets lacking this + password are ignored. This authentication mechanism is very weak. + + authentication [meticulous] keyed md5|sha1 + An authentication code is appended to each packet. The cryptographic + algorithm is keyed MD5 or keyed SHA-1. Note that the algorithm is common + for all keys (on one interface), in contrast to OSPF or RIP, where it + is a per-key option. Passwords (keys) are not sent open via network. + + The password "text" + Specifies a password used for authentication. See common option for detailed description. Note that + password option Example diff --git a/proto/bfd/bfd.c b/proto/bfd/bfd.c index e7be6a8a..79135fae 100644 --- a/proto/bfd/bfd.c +++ b/proto/bfd/bfd.c @@ -316,6 +316,7 @@ bfd_session_timeout(struct bfd_session *s) s->rem_min_rx_int = 1; s->rem_demand_mode = 0; s->rem_detect_mult = 0; + s->rx_csn_known = 0; s->poll_active = 0; s->poll_scheduled = 0; @@ -429,6 +430,7 @@ bfd_add_session(struct bfd_proto *p, ip_addr addr, ip_addr local, struct iface * s->rem_min_rx_int = 1; s->detect_mult = ifa->cf->multiplier; s->passive = ifa->cf->passive; + s->tx_csn = random_u32(); s->tx_timer = tm2_new_init(p->tpool, bfd_tx_timer_hook, s, 0, 0); s->hold_timer = tm2_new_init(p->tpool, bfd_hold_timer_hook, s, 0, 0); diff --git a/proto/bfd/bfd.h b/proto/bfd/bfd.h index 9b61be64..46e09879 100644 --- a/proto/bfd/bfd.h +++ b/proto/bfd/bfd.h @@ -14,6 +14,7 @@ #include "nest/iface.h" #include "nest/protocol.h" #include "nest/route.h" +#include "nest/password.h" #include "conf/conf.h" #include "lib/hash.h" #include "lib/resource.h" @@ -52,6 +53,8 @@ struct bfd_iface_config u32 idle_tx_int; u8 multiplier; u8 passive; + u8 auth_type; /* Authentication type (BFD_AUTH_*) */ + list *passwords; /* Passwords for authentication */ }; struct bfd_neighbor @@ -114,7 +117,7 @@ struct bfd_session u8 passive; u8 poll_active; u8 poll_scheduled; - + u8 loc_state; u8 rem_state; u8 loc_diag; @@ -141,6 +144,11 @@ struct bfd_session list request_list; /* List of client requests (struct bfd_request) */ bird_clock_t last_state_change; /* Time of last state change */ u8 notify_running; /* 1 if notify hooks are running */ + + u8 rx_csn_known; /* Received crypto sequence number is known */ + u32 rx_csn; /* Last received crypto sequence number */ + u32 tx_csn; /* Last transmitted crypto sequence number */ + u32 tx_csn_time; /* Timestamp of last tx_csn change */ }; @@ -172,6 +180,15 @@ extern const char *bfd_state_names[]; #define BFD_FLAG_DEMAND (1 << 1) #define BFD_FLAG_MULTIPOINT (1 << 0) +#define BFD_AUTH_NONE 0 +#define BFD_AUTH_SIMPLE 1 +#define BFD_AUTH_KEYED_MD5 2 +#define BFD_AUTH_METICULOUS_KEYED_MD5 3 +#define BFD_AUTH_KEYED_SHA1 4 +#define BFD_AUTH_METICULOUS_KEYED_SHA1 5 + +extern const u8 bfd_auth_type_to_hash_alg[]; + static inline void bfd_lock_sessions(struct bfd_proto *p) { pthread_spin_lock(&p->lock); } static inline void bfd_unlock_sessions(struct bfd_proto *p) { pthread_spin_unlock(&p->lock); } diff --git a/proto/bfd/config.Y b/proto/bfd/config.Y index 4affb927..73414362 100644 --- a/proto/bfd/config.Y +++ b/proto/bfd/config.Y @@ -22,11 +22,12 @@ extern struct bfd_config *bfd_cf; CF_DECLS CF_KEYWORDS(BFD, MIN, IDLE, RX, TX, INTERVAL, MULTIPLIER, PASSIVE, - INTERFACE, MULTIHOP, NEIGHBOR, DEV, LOCAL) + INTERFACE, MULTIHOP, NEIGHBOR, DEV, LOCAL, AUTHENTICATION, + NONE, SIMPLE, METICULOUS, KEYED, MD5, SHA1) %type bfd_neigh_iface %type bfd_neigh_local -%type bfd_neigh_multihop +%type bfd_neigh_multihop bfd_auth_type CF_GRAMMAR @@ -62,12 +63,35 @@ bfd_proto: bfd_iface_start: { this_ipatt = cfg_allocz(sizeof(struct bfd_iface_config)); + add_tail(&BFD_CFG->patt_list, NODE this_ipatt); init_list(&this_ipatt->ipn_list); BFD_IFACE->min_rx_int = BFD_DEFAULT_MIN_RX_INT; BFD_IFACE->min_tx_int = BFD_DEFAULT_MIN_TX_INT; BFD_IFACE->idle_tx_int = BFD_DEFAULT_IDLE_TX_INT; BFD_IFACE->multiplier = BFD_DEFAULT_MULTIPLIER; + + reset_passwords(); +}; + +bfd_iface_finish: +{ + BFD_IFACE->passwords = get_passwords(); + + if (!BFD_IFACE->auth_type != !BFD_IFACE->passwords) + log(L_WARN "Authentication and password options should be used together"); + + if (BFD_IFACE->passwords) + { + struct password_item *pass; + WALK_LIST(pass, *BFD_IFACE->passwords) + { + if (pass->alg) + cf_error("Password algorithm option not available in BFD protocol"); + + pass->alg = bfd_auth_type_to_hash_alg[BFD_IFACE->auth_type]; + } + } }; bfd_iface_item: @@ -77,6 +101,17 @@ bfd_iface_item: | IDLE TX INTERVAL expr_us { BFD_IFACE->idle_tx_int = $4; } | MULTIPLIER expr { BFD_IFACE->multiplier = $2; } | PASSIVE bool { BFD_IFACE->passive = $2; } + | AUTHENTICATION bfd_auth_type { BFD_IFACE->auth_type = $2; } + | password_list {} + ; + +bfd_auth_type: + NONE { $$ = BFD_AUTH_NONE; } + | SIMPLE { $$ = BFD_AUTH_SIMPLE; } + | KEYED MD5 { $$ = BFD_AUTH_KEYED_MD5; } + | KEYED SHA1 { $$ = BFD_AUTH_KEYED_SHA1; } + | METICULOUS KEYED MD5 { $$ = BFD_AUTH_METICULOUS_KEYED_MD5; } + | METICULOUS KEYED SHA1 { $$ = BFD_AUTH_METICULOUS_KEYED_SHA1; } ; bfd_iface_opts: @@ -89,10 +124,11 @@ bfd_iface_opt_list: | '{' bfd_iface_opts '}' ; -bfd_iface: bfd_iface_start iface_patt_list_nopx bfd_iface_opt_list -{ add_tail(&BFD_CFG->patt_list, NODE this_ipatt); }; +bfd_iface: + bfd_iface_start iface_patt_list_nopx bfd_iface_opt_list bfd_iface_finish; -bfd_multihop: bfd_iface_start bfd_iface_opt_list +bfd_multihop: + bfd_iface_start bfd_iface_opt_list bfd_iface_finish { BFD_CFG->multihop = BFD_IFACE; }; diff --git a/proto/bfd/packets.c b/proto/bfd/packets.c index deb501fc..129db72f 100644 --- a/proto/bfd/packets.c +++ b/proto/bfd/packets.c @@ -5,24 +5,60 @@ */ #include "bfd.h" +#include "lib/mac.h" struct bfd_ctl_packet { - u8 vdiag; /* version and diagnostic */ - u8 flags; /* state and flags */ + u8 vdiag; /* Version and diagnostic */ + u8 flags; /* State and flags */ u8 detect_mult; - u8 length; - u32 snd_id; /* sender ID, aka 'my discriminator' */ - u32 rcv_id; /* receiver ID, aka 'your discriminator' */ + u8 length; /* Whole packet length */ + u32 snd_id; /* Sender ID, aka 'my discriminator' */ + u32 rcv_id; /* Receiver ID, aka 'your discriminator' */ u32 des_min_tx_int; u32 req_min_rx_int; u32 req_min_echo_rx_int; }; +struct bfd_auth +{ + u8 type; /* Authentication type (BFD_AUTH_*) */ + u8 length; /* Authentication section length */ +}; + +struct bfd_simple_auth +{ + u8 type; /* BFD_AUTH_SIMPLE */ + u8 length; /* Length of bfd_simple_auth + pasword length */ + u8 key_id; /* Key ID */ + byte password[0]; /* Password itself, variable length */ +}; + +#define BFD_MAX_PASSWORD_LENGTH 16 + +struct bfd_crypto_auth +{ + u8 type; /* BFD_AUTH_*_MD5 or BFD_AUTH_*_SHA1 */ + u8 length; /* Length of bfd_crypto_auth + hash length */ + u8 key_id; /* Key ID */ + u8 zero; /* Reserved, zero on transmit */ + u32 csn; /* Cryptographic sequence number */ + byte data[0]; /* Authentication key/hash, length 16 or 20 */ +}; + #define BFD_BASE_LEN sizeof(struct bfd_ctl_packet) #define BFD_MAX_LEN 64 +#define DROP(DSC,VAL) do { err_dsc = DSC; err_val = VAL; goto drop; } while(0) + +#define LOG_PKT(msg, args...) \ + log(L_REMOTE "%s: " msg, p->p.name, args) + +#define LOG_PKT_AUTH(msg, args...) \ + log(L_AUTH "%s: " msg, p->p.name, args) + + static inline u8 bfd_pack_vdiag(u8 version, u8 diag) { return (version << 5) | diag; } @@ -59,6 +95,189 @@ bfd_format_flags(u8 flags, char *buf) return buf; } +const u8 bfd_auth_type_to_hash_alg[] = { + [BFD_AUTH_NONE] = ALG_UNDEFINED, + [BFD_AUTH_SIMPLE] = ALG_UNDEFINED, + [BFD_AUTH_KEYED_MD5] = ALG_MD5, + [BFD_AUTH_METICULOUS_KEYED_MD5] = ALG_MD5, + [BFD_AUTH_KEYED_SHA1] = ALG_SHA1, + [BFD_AUTH_METICULOUS_KEYED_SHA1] = ALG_SHA1, +}; + + +/* Fill authentication section and modifies final length in control section packet */ +static void +bfd_fill_authentication(struct bfd_proto *p, struct bfd_session *s, struct bfd_ctl_packet *pkt) +{ + struct bfd_iface_config *cf = s->ifa->cf; + struct password_item *pass = password_find(cf->passwords, 0); + uint meticulous = 0; + + if (!pass) + { + /* FIXME: This should not happen */ + log(L_ERR "%s: No suitable password found for authentication", p->p.name); + return; + } + + switch (cf->auth_type) + { + case BFD_AUTH_SIMPLE: + { + struct bfd_simple_auth *auth = (void *) (pkt + 1); + uint pass_len = MIN(pass->length, BFD_MAX_PASSWORD_LENGTH); + + auth->type = BFD_AUTH_SIMPLE; + auth->length = sizeof(struct bfd_simple_auth) + pass_len; + auth->key_id = pass->id; + + pkt->flags |= BFD_FLAG_AP; + pkt->length += auth->length; + + memcpy(auth->password, pass->password, pass_len); + return; + } + + case BFD_AUTH_METICULOUS_KEYED_MD5: + case BFD_AUTH_METICULOUS_KEYED_SHA1: + meticulous = 1; + + case BFD_AUTH_KEYED_MD5: + case BFD_AUTH_KEYED_SHA1: + { + struct bfd_crypto_auth *auth = (void *) (pkt + 1); + uint hash_alg = bfd_auth_type_to_hash_alg[cf->auth_type]; + uint hash_len = mac_type_length(pass->alg); + + /* Increase CSN about one time per second */ + u32 new_time = (u64) current_time() >> 20; + if ((new_time != s->tx_csn_time) || meticulous) + { + s->tx_csn++; + s->tx_csn_time = new_time; + } + + DBG("[%I] CSN: %u\n", s->addr, s->last_tx_csn); + + auth->type = cf->auth_type; + auth->length = sizeof(struct bfd_crypto_auth) + hash_len; + auth->key_id = pass->id; + auth->zero = 0; + auth->csn = htonl(s->tx_csn); + + pkt->flags |= BFD_FLAG_AP; + pkt->length += auth->length; + + strncpy(auth->data, pass->password, hash_len); + mac_fill(hash_alg, NULL, 0, (byte *) pkt, pkt->length, auth->data); + return; + } + } +} + +static int +bfd_check_authentication(struct bfd_proto *p, struct bfd_session *s, struct bfd_ctl_packet *pkt) +{ + struct bfd_iface_config *cf = s->ifa->cf; + const char *err_dsc = NULL; + uint err_val = 0; + uint auth_type = 0; + uint meticulous = 0; + + if (pkt->flags & BFD_FLAG_AP) + { + struct bfd_auth *auth = (void *) (pkt + 1); + + if ((pkt->length < (BFD_BASE_LEN + sizeof(struct bfd_auth))) || + (pkt->length < (BFD_BASE_LEN + auth->length))) + DROP("packet length mismatch", pkt->length); + + /* Zero is reserved, we use it as BFD_AUTH_NONE internally */ + if (auth->type == 0) + DROP("reserved authentication type", 0); + + auth_type = auth->type; + } + + if (auth_type != cf->auth_type) + DROP("authentication method mismatch", auth_type); + + switch (auth_type) + { + case BFD_AUTH_NONE: + return 1; + + case BFD_AUTH_SIMPLE: + { + struct bfd_simple_auth *auth = (void *) (pkt + 1); + + if (auth->length < sizeof(struct bfd_simple_auth)) + DROP("wrong authentication length", auth->length); + + struct password_item *pass = password_find_by_id(cf->passwords, auth->key_id); + if (!pass) + DROP("no suitable password found", auth->key_id); + + uint pass_len = MIN(pass->length, BFD_MAX_PASSWORD_LENGTH); + uint auth_len = sizeof(struct bfd_simple_auth) + pass_len; + + if ((auth->length != auth_len) || memcmp(auth->password, pass->password, pass_len)) + DROP("wrong password", pass->id); + + return 1; + } + + case BFD_AUTH_METICULOUS_KEYED_MD5: + case BFD_AUTH_METICULOUS_KEYED_SHA1: + meticulous = 1; + + case BFD_AUTH_KEYED_MD5: + case BFD_AUTH_KEYED_SHA1: + { + struct bfd_crypto_auth *auth = (void *) (pkt + 1); + uint hash_alg = bfd_auth_type_to_hash_alg[cf->auth_type]; + uint hash_len = mac_type_length(hash_alg); + + if (auth->length != (sizeof(struct bfd_crypto_auth) + hash_len)) + DROP("wrong authentication length", auth->length); + + struct password_item *pass = password_find_by_id(cf->passwords, auth->key_id); + if (!pass) + DROP("no suitable password found", auth->key_id); + + /* BFD CSNs are in 32-bit circular number space */ + u32 csn = ntohl(auth->csn); + if (s->rx_csn_known && + (((csn - s->rx_csn) > (3 * s->detect_mult)) || + (meticulous && (csn == s->rx_csn)))) + { + /* We want to report both new and old CSN */ + LOG_PKT_AUTH("Authentication failed for %I - " + "wrong sequence number (rcv %u, old %u)", + s->addr, csn, s->rx_csn); + return 0; + } + + byte *auth_data = alloca(hash_len); + memcpy(auth_data, auth->data, hash_len); + strncpy(auth->data, pass->password, hash_len); + + if (!mac_verify(hash_alg, NULL, 0, (byte *) pkt, pkt->length, auth_data)) + DROP("wrong authentication code", pass->id); + + s->rx_csn = csn; + s->rx_csn_known = 1; + + return 1; + } + } + +drop: + LOG_PKT_AUTH("Authentication failed for %I - %s (%u)", + s->addr, err_dsc, err_val); + return 0; +} + void bfd_send_ctl(struct bfd_proto *p, struct bfd_session *s, int final) { @@ -85,6 +304,9 @@ bfd_send_ctl(struct bfd_proto *p, struct bfd_session *s, int final) else if (s->poll_active) pkt->flags |= BFD_FLAG_POLL; + if (s->ifa->cf->auth_type) + bfd_fill_authentication(p, s, pkt); + if (sk->tbuf != sk->tpos) log(L_WARN "%s: Old packet overwritten in TX buffer", p->p.name); @@ -94,8 +316,6 @@ bfd_send_ctl(struct bfd_proto *p, struct bfd_session *s, int final) sk_send_to(sk, pkt->length, s->addr, sk->dport); } -#define DROP(DSC,VAL) do { err_dsc = DSC; err_val = VAL; goto drop; } while(0) - static int bfd_rx_hook(sock *sk, uint len) { @@ -151,10 +371,9 @@ bfd_rx_hook(sock *sk, uint len) return 1; } - /* FIXME: better authentication handling and message */ - if (pkt->flags & BFD_FLAG_AP) - DROP("authentication not supported", 0); - + /* bfd_check_authentication() has its own error logging */ + if (!bfd_check_authentication(p, s, pkt)) + return 1; u32 old_tx_int = s->des_min_tx_int; u32 old_rx_int = s->rem_min_rx_int; @@ -173,8 +392,8 @@ bfd_rx_hook(sock *sk, uint len) bfd_session_process_ctl(s, pkt->flags, old_tx_int, old_rx_int); return 1; - drop: - log(L_REMOTE "%s: Bad packet from %I - %s (%u)", p->p.name, sk->faddr, err_dsc, err_val); +drop: + LOG_PKT("Bad packet from %I - %s (%u)", sk->faddr, err_dsc, err_val); return 1; } -- cgit v1.2.3