[-]
[+]
|
Changed |
bird.changes
|
|
[-]
[+]
|
Changed |
bird.spec
^
|
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/ChangeLog
^
|
@@ -1,3 +1,185 @@
+commit 16fc65acc536d3788efe4c0554a2f52699fedc7f
+Author: Ondrej Filip <feela@network.cz>
+Date: Thu Mar 22 14:52:40 2012 +0100
+
+ Minor correction
+
+commit 89647357af0d8507652f257f1e8f5679fe9a7078
+Author: Ondrej Zajicek <santiago@crfreenet.org>
+Date: Thu Mar 22 12:29:02 2012 +0100
+
+ NEWS and version update.
+
+commit c47d037ecb5b9c835700b152eed7589409a2e42f
+Author: Ondrej Zajicek <santiago@crfreenet.org>
+Date: Thu Mar 22 11:46:38 2012 +0100
+
+ Some minor changes to CLI.
+
+commit df27911880bffb88c1eae90e36c755a3ed3d77ad
+Author: Ondrej Zajicek <santiago@crfreenet.org>
+Date: Mon Mar 19 13:00:00 2012 +0100
+
+ Fixes problem with dirname().
+
+ Thanks Henrique de Moraes Holschuh for the original patch.
+
+commit af582c4811175d9a27ed5d08a4f6d5eaa69ecec7
+Author: Ondrej Zajicek <santiago@crfreenet.org>
+Date: Sun Mar 18 17:32:30 2012 +0100
+
+ Route Origin Authorization basics.
+
+ - ROA tables, which are used as a basic part for RPKI.
+ - Commands for examining and modifying ROA tables.
+ - Filter operators based on ROA tables consistent with RFC 6483.
+
+commit fd087589f80a435a42cedb87b917c71363b11860
+Author: Ondrej Zajicek <santiago@crfreenet.org>
+Date: Fri Mar 16 13:01:12 2012 +0100
+
+ Fixes broken vlinks in OSPF.
+
+commit 0f808c066f3b5b190de951db042a34a1eb957a16
+Author: Ondrej Zajicek <santiago@crfreenet.org>
+Date: Fri Mar 16 12:47:12 2012 +0100
+
+ Adds filtering to 'show symbols' command.
+
+ Thanks Alexander V. Chernikov for the original patch.
+
+commit 20ab192beca749166e19118e987b53b5e131d0cf
+Author: Ondrej Zajicek <santiago@crfreenet.org>
+Date: Fri Mar 16 12:12:26 2012 +0100
+
+ Adds filtering to 'show ospf lsadb' command.
+
+ Thanks Alexander V. Chernikov for the original patch.
+
+commit 0888a737b045b48106edbd28ba3cd62fcc8c191e
+Author: Ondrej Zajicek <santiago@crfreenet.org>
+Date: Thu Mar 15 20:42:29 2012 +0100
+
+ Extends set operations in filters.
+
+ Allows add/filter/delete clist on clist (set algebra on clists).
+
+ Allows number ~ bgppath match.
+
+commit 9f1500f50a0196f912eeb97e77ccf6873e186c29
+Author: Ondrej Zajicek <santiago@crfreenet.org>
+Date: Thu Mar 15 13:45:55 2012 +0100
+
+ Adds warning for mismatch MTU in OSPF packets.
+
+ Thanks Alexander V. Chernikov for the original patch.
+
+commit 2f9955b5d508698b04ff41e5e38097acdac416b9
+Author: Ondrej Zajicek <santiago@crfreenet.org>
+Date: Thu Mar 15 13:12:00 2012 +0100
+
+ Fixes TTL for multicast OSPF packets.
+
+ Thanks Alexander V. Chernikov for the suggestion.
+
+commit 8796a8a56edbcd420de724a58947c7aedadf04de
+Author: Ondrej Zajicek <santiago@crfreenet.org>
+Date: Thu Mar 15 12:50:49 2012 +0100
+
+ Fixes name for unnamed filters.
+
+ Thanks to Alexander V. Chernikov for the suggestion.
+
+commit 7d837aa014a78bce2b329cc9f56e8dc799d456e8
+Author: Ondrej Zajicek <santiago@crfreenet.org>
+Date: Thu Mar 15 12:43:47 2012 +0100
+
+ Fixes documentation - default pipe mode.
+
+ Thanks to Benjamin Cama for the bugreport.
+
+commit e2bf812f3dc84981eac045b617261987c25b5e90
+Author: Ondrej Zajicek <santiago@crfreenet.org>
+Date: Thu Mar 15 12:38:08 2012 +0100
+
+ Fixes RIPng compatibility.
+
+ Also probably breaks compatibility with older BIRDs, but RIPng not
+ really worked here.
+
+ Thanks to Goesta Smekal for the original patch.
+
+commit f761503760fba2d4124cc3352f5260c31fac526d
+Author: Ondrej Zajicek <santiago@crfreenet.org>
+Date: Thu Mar 15 12:23:49 2012 +0100
+
+ Fixes RIPng socket and neighbor handling.
+
+ RIPng did not really work because of link-local addresses.
+
+ Thanks to Roman Hoog Antink for some notes.
+
+commit 117e3c4bbfd4b7f1b2cae6ef9e5cb603fe33307a
+Author: Ondrej Zajicek <santiago@crfreenet.org>
+Date: Thu Mar 15 12:18:26 2012 +0100
+
+ Fixes a bug in pair set intervals.
+
+ Pair intervals in form (a,b)..(c,d) were mishanded.
+
+ Thanks to Alexander Shikoff for the bugreport.
+
+commit 46c1a583a5c1ea81e8d8f372bd7f614506a63938
+Author: Ondrej Zajicek <santiago@crfreenet.org>
+Date: Fri Feb 3 11:50:51 2012 +0100
+
+ Fixes a bug causing crash during soft reconfiguration of export to kernel proto.
+
+commit 39c028e9e9e3acf840051f4271fadd4939fde2af
+Author: Ondrej Zajicek <santiago@crfreenet.org>
+Date: Tue Jan 24 11:31:00 2012 +0100
+
+ Assign default protocol preference via proto_config_new().
+
+ The patch from Alexander V. Chernikov.
+
+commit 09686693d35bd71187847c95c0967d4125215b97
+Author: Ondrej Zajicek <santiago@crfreenet.org>
+Date: Mon Jan 23 03:15:12 2012 +0100
+
+ Implements handling of BSD iface arrival/departure notifications.
+
+ Thanks to Alexander V. Chernikov for original patch.
+
+commit 732a0a257d180a95a02587203555b8552b6128ac
+Author: Ondrej Zajicek <santiago@crfreenet.org>
+Date: Mon Jan 23 01:26:40 2012 +0100
+
+ Fixes problems with creating/removing/renaming ifaces on BSD.
+
+commit 5c78e0e386d4c770b646cab4a8adc3c87987f50f
+Author: Ondrej Zajicek <santiago@crfreenet.org>
+Date: Sun Jan 22 11:03:30 2012 +0100
+
+ Some more verbose warnings.
+
+commit bc092571171d00de8b429fec8ba70c39240d7e91
+Author: Ondrej Zajicek <santiago@crfreenet.org>
+Date: Sat Jan 21 22:56:16 2012 +0100
+
+ Fixes another minor bug in iface scan.
+
+ Iface flags are not updated in some cases.
+
+commit b573755df426156c22d2a4c65e3f502284820166
+Author: Ondrej Zajicek <santiago@crfreenet.org>
+Date: Sat Jan 21 22:41:31 2012 +0100
+
+ Fixes a bug in BSD iface scan.
+
+ if_update() should be called always, because periodic iface scan code
+ removes all not-updated ifaces.
+
commit 544f2e1b36fb9473132f77d9c0f6e97d1495bb24
Author: Ondrej Zajicek <santiago@crfreenet.org>
Date: Fri Jan 20 18:16:35 2012 +0100
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/NEWS
^
|
@@ -1,4 +1,11 @@
+Version 1.3.7 (2012-03-22)
+ o Route Origin Authorization basics.
+ o RIPng working again.
+ o Extended clist operations in filters.
+ o Fixes several bugs in BSD iface handling.
+ o Several minor bugfixes and enhancements.
+
Version 1.3.6 (2012-01-20)
o Important bugfix in BGP.
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/TODO
^
|
@@ -2,7 +2,6 @@
~~~~
- socket open failure should not be fatal
- &&,||: priorities
-- filters: function for BGP path length
- static: allow specifying a per-route filter program for setting route attributes?
Globals
@@ -23,14 +22,10 @@
~~~~~~~~~~~~~
- client: Ctrl-R eats one more enter
- bgp: timing of updates?
-- netlink: realms
- netlink: import Linux route attributes to our rta's, so that they can be filtered?
- config: executable config files
- filters: user defined attributes?
-- client: access control
- io: use poll if available
-- real multipath (doesn't seem to be simple at all :()
-- fake multipath (even less simple)
- route recalculation timing and flap dampening [see RFC2439 for algorithms]
- aggregate engine: standard route aggregation and summarization [RFC2519]
- aggregate engine: injection of manually configured pseudo-static routes
@@ -44,7 +39,6 @@
- check incoming packets using neighbor cache
- RFC2328 appendix E: Use a better algorithm
- automatic generation of external route tags (RFC1403)
- - RFC3101 NSSA areas
- RFC2370 opaque LSA's
- Limit export rate of external LSAs (like Gated does)
- Bugfix in link state retransmission list (aging)
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/client/commands.c
^
|
@@ -29,6 +29,7 @@
struct cmd_node *sibling, *son, **plastson;
struct cmd_info *cmd, *help;
int len;
+ signed char prio;
char token[1];
};
@@ -66,6 +67,7 @@
new->plastson = &new->son;
new->len = c-d;
memcpy(new->token, d, c-d);
+ new->prio = (new->len == 3 && !memcmp(new->token, "roa", 3)) ? 0 : 1; /* Hack */
}
old = new;
while (isspace(*c))
@@ -108,7 +110,10 @@
return m;
if (m->len > len && !memcmp(m->token, cmd, len))
{
- best2 = best;
+ if (best && best->prio > m->prio)
+ continue;
+ if (best && best->prio == m->prio)
+ best2 = best;
best = m;
}
}
@@ -168,19 +173,31 @@
cmd_find_common_match(struct cmd_node *root, char *cmd, int len, int *pcount, char *buf)
{
struct cmd_node *m;
- int best, i;
+ int best, best_prio, i;
*pcount = 0;
best = -1;
+ best_prio = -1;
for(m=root->son; m; m=m->sibling)
{
if (m->len < len || memcmp(m->token, cmd, len))
continue;
+
+ if (best_prio > m->prio)
+ continue;
+
+ if (best_prio < m->prio)
+ {
+ *pcount = 0;
+ best = -1;
+ }
+
(*pcount)++;
if (best < 0)
{
strcpy(buf, m->token + len);
best = m->len - len;
+ best_prio = m->prio;
}
else
{
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/conf/cf-lex.l
^
|
@@ -536,6 +536,8 @@
return "network address";
case SYM_TEMPLATE:
return "protocol template";
+ case SYM_ROA:
+ return "ROA table";
default:
return "unknown type";
}
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/conf/conf.c
^
|
@@ -112,6 +112,7 @@
sysdep_preconfig(c);
protos_preconfig(c);
rt_preconfig(c);
+ roa_preconfig(c);
cf_parse();
protos_postconfig(c);
if (EMPTY_LIST(c->protos))
@@ -210,6 +211,7 @@
force_restart |= global_commit(c, old_config);
DBG("rt_commit\n");
rt_commit(c, old_config);
+ roa_commit(c, old_config);
DBG("protos_commit\n");
protos_commit(c, old_config, force_restart, type);
new_config = NULL; /* Just to be sure nobody uses that now */
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/conf/conf.h
^
|
@@ -21,7 +21,9 @@
linpool *mem; /* Linear pool containing configuration data */
list protos; /* Configured protocol instances (struct proto_config) */
list tables; /* Configured routing tables (struct rtable_config) */
+ list roa_tables; /* Configured ROA tables (struct roa_table_config) */
list logfiles; /* Configured log fils (sysdep) */
+
int mrtdump_file; /* Configured MRTDump file (sysdep, fd in unix) */
char *syslog_name; /* Name used for syslog (NULL -> no syslog) */
struct rtable_config *master_rtc; /* Configuration of master routing table */
@@ -110,6 +112,7 @@
#define SYM_TABLE 5
#define SYM_IPA 6
#define SYM_TEMPLATE 7
+#define SYM_ROA 8
#define SYM_VARIABLE 0x100 /* 0x100-0x1ff are variable types */
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/conf/confbase.Y
^
|
@@ -50,7 +50,11 @@
struct f_path_mask *h;
struct password_item *p;
struct rt_show_data *ra;
+ struct roa_show_data *ro;
+ struct sym_show_data *sd;
+ struct lsadb_show_data *ld;
struct iface *iface;
+ struct roa_table *rot;
void *g;
bird_clock_t time;
struct prefix px;
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/doc/bird-3.html
^
|
@@ -145,6 +145,20 @@
routing table is created implicitly, other routing tables have
to be added by this command.
<P>
+<DT><CODE>roa table [ { roa table options ... } ] <I>name</I></CODE><DD><P>Create a new ROA (Route Origin Authorization) table. ROA
+tables can be 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 <CODE>roa_check()</CODE> operator in filters.
+<P>Currently, there is just one option,
+<CODE>roa <I>prefix</I> max <I>num</I> as <I>num</I></CODE>, which
+can be used to populate the ROA table with static ROA
+entries. The option may be used multiple times. Other entries
+can be added dynamically by <CODE>add roa</CODE> command.
+<P>
<DT><CODE>eval <I>expr</I></CODE><DD><P>Evaluates given filter expression. It
is used by us for testing of filters.
</DL>
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/doc/bird-4.html
^
|
@@ -55,11 +55,13 @@
link-state database. It is just a stripped-down version of
'show ospf state'.
<P>
+<DT><CODE>show ospf lsadb [global | area <I>id</I> | link] [type <I>num</I>] [lsid <I>id</I>] [self | router <I>id</I>] [<I>name</I>] </CODE><DD><P>Show contents of an OSPF LSA database. Options could be used to filter entries.
+<P>
<DT><CODE>show static [<I>name</I>]</CODE><DD><P>Show detailed information about static routes.
<P>
<DT><CODE>show interfaces [summary]</CODE><DD><P>Show the list of interfaces. For each interface, print its type, state, MTU and addresses assigned.
<P>
-<DT><CODE>show symbols</CODE><DD><P>Show the list of symbols defined in the configuration (names of protocols, routing tables etc.).
+<DT><CODE>show symbols [table|filter|function|protocol|template|roa|<I>symbol</I>]</CODE><DD><P>Show the list of symbols defined in the configuration (names of protocols, routing tables etc.).
<P>
<DT><CODE>show route [[for] <I>prefix</I>|<I>IP</I>] [table <I>sym</I>] [filter <I>f</I>|where <I>c</I>] [(export|preexport) <I>p</I>] [protocol <I>p</I>] [<I>options</I>]</CODE><DD><P>Show contents of a routing table (by default of the main one),
that is routes, their metrics and (in case the <CODE>all</CODE> switch is given)
@@ -85,6 +87,25 @@
number of networks, number of routes before and after filtering). If
you use <CODE>count</CODE> instead, only the statistics will be printed.
<P>
+<DT><CODE>show roa [<I>prefix</I> | in <I>prefix</I> | for <I>prefix</I>] [as <I>num</I>] [table <I>t</I>>]</CODE><DD><P>Show contents of a ROA table (by default of the first one).
+You can specify a <I>prefix</I> to print ROA entries for a
+specific network. If you use <CODE>for <I>prefix</I></CODE>, you'll
+get all entries relevant for route validation of the network
+prefix; i.e., ROA entries whose prefixes cover the network
+prefix. Or you can use <CODE>in <I>prefix</I></CODE> to get ROA entries
+covered by the network prefix. You could also use <CODE>as</CODE> option
+to show just entries for given AS.
+<P>
+<DT><CODE>add roa <I>prefix</I> max <I>num</I>] as <I>num</I> [table <I>t</I>>]</CODE><DD><P>Add a new ROA entry to a ROA table. Such entry is called
+<I>dynamic</I> compared to <I>static</I> entries specified in the
+config file. These dynamic entries survive reconfiguration.
+<P>
+<DT><CODE>delete roa <I>prefix</I> max <I>num</I>] as <I>num</I> [table <I>t</I>>]</CODE><DD><P>Delete the specified ROA entry from a ROA table. Only dynamic
+ROA entries (i.e., the ones added by <CODE>add roa</CODE> command) can
+be deleted.
+<P>
+<DT><CODE>flush roa [table <I>t</I>>]</CODE><DD><P>Remove all dynamic ROA entries from a ROA table.
+<P>
<DT><CODE>configure [soft] ["<I>config file</I>"]</CODE><DD><P>Reload configuration from a given file. BIRD will smoothly
switch itself to the new configuration, protocols are
reconfigured if possible, restarted otherwise. Changes in
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/doc/bird-5.html
^
|
@@ -242,17 +242,20 @@
clists:
<P><CODE>add(<I>C</I>,<I>P</I>)</CODE> adds pair (or quad) <I>P</I> to clist
<I>C</I> and returns the result. If item <I>P</I> is already in
-clist <I>C</I>, it does nothing.
+clist <I>C</I>, it does nothing. <I>P</I> may also be a clist,
+in that case all its members are added; i.e., it works as clist union.
<P><CODE>delete(<I>C</I>,<I>P</I>)</CODE> deletes pair (or quad)
<I>P</I> from clist <I>C</I> and returns the result. If clist
<I>C</I> does not contain item <I>P</I>, it does nothing.
<I>P</I> may also be a pair (or quad) set, in that case the
operator deletes all items from clist <I>C</I> that are also
-members of set <I>P</I>.
+members of set <I>P</I>. Moreover, <I>P</I> may also be a clist,
+which works analogously; i.e., it works as clist difference.
<P><CODE>filter(<I>C</I>,<I>P</I>)</CODE> deletes all items from clist
<I>C</I> that are not members of pair (or quad) set <I>P</I>.
I.e., <CODE>filter</CODE> do the same as <CODE>delete</CODE> with inverted
-set <I>P</I>.
+set <I>P</I>. <I>P</I> may also be a clist, which works analogously;
+i.e., it works as clist intersection.
<P>Statement <CODE><I>C</I> = add(<I>C</I>, <I>P</I>);</CODE> can be shortened to
<CODE><I>C</I>.add(<I>P</I>);</CODE> if <I>C</I> is appropriate route
attribute (for example <CODE>bgp_community</CODE>). Similarly for
@@ -274,7 +277,18 @@
Special operators include <CODE>~</CODE> for "is element of a set" operation - it can be
used on element and set of elements of the same type (returning true if element is contained in the given set), or
on two strings (returning true if first string matches a shell-like pattern stored in second string) or on IP and prefix (returning true if IP is within the range defined by that prefix), or on
-prefix and prefix (returning true if first prefix is more specific than second one) or on bgppath and bgpmask (returning true if the path matches the mask) or on pair/quad and clist (returning true if the pair/quad is element of the 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).
+prefix and prefix (returning true if first prefix is more specific than second one) or on bgppath and bgpmask (returning true if the path matches the mask) or on number and bgppath (returning true if the number is in the path) or on pair/quad and clist (returning true if the pair/quad is element of the 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).
+<P>
+<P>There is one operator related to ROA infrastructure -
+<CODE>roa_check()</CODE>. It examines a ROA table and does RFC 6483 route
+origin validation for a given network prefix. The basic usage
+is <CODE>roa_check(<I>table</I>)</CODE>, 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
+<CODE>roa_check(<I>table</I>, <I>prefix</I>, <I>asn</I>)</CODE>, which allows to
+specify a prefix and an ASN as arguments.
<P>
<P>
<H2><A NAME="ss5.4">5.4</A> <A HREF="bird.html#toc5.4">Control structures</A>
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/doc/bird-6.html
^
|
@@ -1072,17 +1072,18 @@
of routes from the primary table to the secondary one, import filters control the opposite
direction.
<P>
-<P>The Pipe protocol may work in the opaque mode or in the transparent
-mode. In the opaque mode, the Pipe protocol retransmits optimal route
+<P>The Pipe protocol may work in the transparent mode mode or in the opaque mode.
+In the transparent mode, the Pipe protocol retransmits all routes from
+one table to the other table, retaining their original source and
+attributes. If import and export filters are set to accept, then both
+tables would have the same content. The transparent mode is the default mode.
+<P>
+<P>In the opaque mode, the Pipe protocol retransmits optimal route
from one table to the other table in a similar way like other
protocols send and receive routes. Retransmitted route will have the
source set to the Pipe protocol, which may limit access to protocol
-specific route attributes. The opaque mode is a default mode.
-<P>
-<P>In transparent mode, the Pipe protocol retransmits all routes from
-one table to the other table, retaining their original source and
-attributes. If import and export filters are set to accept, then both
-tables would have the same content. The mode can be set by
+specific route attributes. This mode is mainly for compatibility, it
+is not suggested for new configs. The mode can be changed by
<CODE>mode</CODE> option.
<P>
<P>The primary use of multiple routing tables and the Pipe protocol is for policy routing,
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/doc/bird.sgml
^
|
@@ -358,6 +358,22 @@
routing table is created implicitly, other routing tables have
to be added by this command.
+ <tag>roa table [ { roa table options ... } ] <m/name/</tag>
+ Create a new ROA (Route Origin Authorization) table. ROA
+ tables can be 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 <cf/roa_check()/ operator in filters.
+
+ Currently, there is just one option,
+ <cf>roa <m/prefix/ max <m/num/ as <m/num/</cf>, which
+ can be used to populate the ROA table with static ROA
+ entries. The option may be used multiple times. Other entries
+ can be added dynamically by <cf/add roa/ command.
+
<tag>eval <m/expr/</tag> Evaluates given filter expression. It
is used by us for testing of filters.
</descrip>
@@ -561,13 +577,16 @@
link-state database. It is just a stripped-down version of
'show ospf state'.
+ <tag>show ospf lsadb [global | area <m/id/ | link] [type <m/num/] [lsid <m/id/] [self | router <m/id/] [<m/name/] </tag>
+ Show contents of an OSPF LSA database. Options could be used to filter entries.
+
<tag>show static [<m/name/]</tag>
Show detailed information about static routes.
<tag>show interfaces [summary]</tag>
Show the list of interfaces. For each interface, print its type, state, MTU and addresses assigned.
- <tag>show symbols</tag>
+ <tag>show symbols [table|filter|function|protocol|template|roa|<m/symbol/]</tag>
Show the list of symbols defined in the configuration (names of protocols, routing tables etc.).
<tag>show route [[for] <m/prefix/|<m/IP/] [table <m/sym/] [filter <m/f/|where <m/c/] [(export|preexport) <m/p/] [protocol <m/p/] [<m/options/]</tag>
@@ -596,6 +615,29 @@
number of networks, number of routes before and after filtering). If
you use <cf/count/ instead, only the statistics will be printed.
+ <tag>show roa [<m/prefix/ | in <m/prefix/ | for <m/prefix/] [as <m/num/] [table <m/t/>]</tag>
+ Show contents of a ROA table (by default of the first one).
+ You can specify a <m/prefix/ to print ROA entries for a
+ specific network. If you use <cf>for <m/prefix/</cf>, you'll
+ get all entries relevant for route validation of the network
+ prefix; i.e., ROA entries whose prefixes cover the network
+ prefix. Or you can use <cf>in <m/prefix/</cf> to get ROA entries
+ covered by the network prefix. You could also use <cf/as/ option
+ to show just entries for given AS.
+
+ <tag>add roa <m/prefix/ max <m/num/] as <m/num/ [table <m/t/>]</tag>
+ Add a new ROA entry to a ROA table. Such entry is called
+ <it/dynamic/ compared to <it/static/ entries specified in the
+ config file. These dynamic entries survive reconfiguration.
+
+ <tag>delete roa <m/prefix/ max <m/num/] as <m/num/ [table <m/t/>]</tag>
+ Delete the specified ROA entry from a ROA table. Only dynamic
+ ROA entries (i.e., the ones added by <cf/add roa/ command) can
+ be deleted.
+
+ <tag>flush roa [table <m/t/>]</tag>
+ Remove all dynamic ROA entries from a ROA table.
+
<tag>configure [soft] ["<m/config file/"]</tag>
Reload configuration from a given file. BIRD will smoothly
switch itself to the new configuration, protocols are
@@ -875,19 +917,22 @@
<cf>add(<m/C/,<m/P/)</cf> adds pair (or quad) <m/P/ to clist
<m/C/ and returns the result. If item <m/P/ is already in
- clist <m/C/, it does nothing.
+ clist <m/C/, it does nothing. <m/P/ may also be a clist,
+ in that case all its members are added; i.e., it works as clist union.
<cf>delete(<m/C/,<m/P/)</cf> deletes pair (or quad)
<m/P/ from clist <m/C/ and returns the result. If clist
<m/C/ does not contain item <m/P/, it does nothing.
<m/P/ may also be a pair (or quad) set, in that case the
operator deletes all items from clist <m/C/ that are also
- members of set <m/P/.
+ members of set <m/P/. Moreover, <m/P/ may also be a clist,
+ which works analogously; i.e., it works as clist difference.
<cf>filter(<m/C/,<m/P/)</cf> deletes all items from clist
<m/C/ that are not members of pair (or quad) set <m/P/.
I.e., <cf/filter/ do the same as <cf/delete/ with inverted
- set <m/P/.
+ set <m/P/. <m/P/ may also be a clist, which works analogously;
+ i.e., it works as clist intersection.
Statement <cf><m/C/ = add(<m/C/, <m/P/);</cf> can be shortened to
<cf><m/C/.add(<m/P/);</cf> if <m/C/ is appropriate route
@@ -910,7 +955,18 @@
Special operators include <cf/˜/ for "is element of a set" operation - it can be
used on element and set of elements of the same type (returning true if element is contained in the given set), or
on two strings (returning true if first string matches a shell-like pattern stored in second string) or on IP and prefix (returning true if IP is within the range defined by that prefix), or on
-prefix and prefix (returning true if first prefix is more specific than second one) or on bgppath and bgpmask (returning true if the path matches the mask) or on pair/quad and clist (returning true if the pair/quad is element of the 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).
+prefix and prefix (returning true if first prefix is more specific than second one) or on bgppath and bgpmask (returning true if the path matches the mask) or on number and bgppath (returning true if the number is in the path) or on pair/quad and clist (returning true if the pair/quad is element of the 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).
+
+<p>There is one operator related to ROA infrastructure -
+<cf/roa_check()/. It examines a ROA table and does RFC 6483 route
+origin validation for a given network prefix. The basic usage
+is <cf>roa_check(<m/table/)</cf>, 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
+<cf>roa_check(<m/table/, <m/prefix/, <m/asn/)</cf>, which allows to
+specify a prefix and an ASN as arguments.
<sect>Control structures
@@ -2085,17 +2141,18 @@
of routes from the primary table to the secondary one, import filters control the opposite
direction.
-<p>The Pipe protocol may work in the opaque mode or in the transparent
-mode. In the opaque mode, the Pipe protocol retransmits optimal route
+<p>The Pipe protocol may work in the transparent mode mode or in the opaque mode.
+In the transparent mode, the Pipe protocol retransmits all routes from
+one table to the other table, retaining their original source and
+attributes. If import and export filters are set to accept, then both
+tables would have the same content. The transparent mode is the default mode.
+
+<p>In the opaque mode, the Pipe protocol retransmits optimal route
from one table to the other table in a similar way like other
protocols send and receive routes. Retransmitted route will have the
source set to the Pipe protocol, which may limit access to protocol
-specific route attributes. The opaque mode is a default mode.
-
-<p>In transparent mode, the Pipe protocol retransmits all routes from
-one table to the other table, retaining their original source and
-attributes. If import and export filters are set to accept, then both
-tables would have the same content. The mode can be set by
+specific route attributes. This mode is mainly for compatibility, it
+is not suggested for new configs. The mode can be changed by
<tt/mode/ option.
<p>The primary use of multiple routing tables and the Pipe protocol is for policy routing,
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/doc/prog-2.html
^
|
@@ -1634,6 +1634,22 @@
<HR><H3>Function</H3>
+<P><I>void</I>
+<B>if_delete</B>
+(<I>struct iface *</I> <B>old</B>) -- remove interface
+<P>
+<H3>Arguments</H3>
+<P>
+<DL>
+<DT><I>struct iface *</I> <B>old</B><DD><P>interface
+</DL>
+<H3>Description</H3>
+<P>This function is called by the low-level platform dependent code
+whenever it notices an interface disappears. It is just a shorthand
+for <B>if_update()</B>.
+
+
+<HR><H3>Function</H3>
<P><I>struct iface *</I>
<B>if_update</B>
(<I>struct iface *</I> <B>new</B>) -- update interface status
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/doc/reply_codes
^
|
@@ -45,6 +45,7 @@
1016 Show ospf state/topology
1017 Show ospf lsadb
1018 Show memory
+1019 Show ROA list
8000 Reply too long
8001 Route not found
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/filter/config.Y
^
|
@@ -259,6 +259,7 @@
DEFINED,
ADD, DELETE, CONTAINS, RESET,
PREPEND, FIRST, LAST, MATCH,
+ ROA_CHECK,
EMPTY,
FILTER, WHERE, EVAL)
@@ -495,7 +496,7 @@
/* Hack: $2 and $4 should be pair_expr, but that would cause shift/reduce conflict */
if ((pair_a($2) != pair_b($2)) || (pair_a($4) != pair_b($4)))
cf_error("syntax error");
- $$ = f_new_pair_item(pair_b($2), pair_b($4), $8, $10);
+ $$ = f_new_pair_item(pair_b($2), $8, pair_b($4), $10);
}
;
@@ -755,6 +756,9 @@
| DELETE '(' term ',' term ')' { $$ = f_new_inst(); $$->code = P('C','a'); $$->a1.p = $3; $$->a2.p = $5; $$->aux = 'd'; }
| FILTER '(' term ',' term ')' { $$ = f_new_inst(); $$->code = P('C','a'); $$->a1.p = $3; $$->a2.p = $5; $$->aux = 'f'; }
+ | ROA_CHECK '(' SYM ')' { $$ = f_generate_roa_check($3, NULL, NULL); }
+ | ROA_CHECK '(' SYM ',' term ',' term ')' { $$ = f_generate_roa_check($3, $5, $7); }
+
/* | term '.' LEN { $$->code = P('P','l'); } */
/* function_call is inlined here */
@@ -801,7 +805,6 @@
$$ = $1;
} else $$ = $3;
}
-
;
var_listn: term {
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/filter/f-util.c
^
|
@@ -54,6 +54,24 @@
return set_dyn;
}
+
+struct f_inst *
+f_generate_roa_check(struct symbol *sym, struct f_inst *prefix, struct f_inst *asn)
+{
+ struct f_inst_roa_check *ret = cfg_allocz(sizeof(struct f_inst_roa_check));
+ ret->i.code = P('R','C');
+ ret->i.lineno = ifs->conf_lino;
+ ret->i.arg1 = prefix;
+ ret->i.arg2 = asn;
+ /* prefix == NULL <-> asn == NULL */
+
+ if ((sym->class != SYM_ROA) || ! sym->def)
+ cf_error("%s is not a ROA table", sym->name);
+ ret->rtc = sym->def;
+
+ return &ret->i;
+}
+
char *
filter_name(struct filter *filter)
{
@@ -61,6 +79,8 @@
return "ACCEPT";
else if (filter == FILTER_REJECT)
return "REJECT";
+ else if (!filter->name)
+ return "(unnamed)";
else
return filter->name;
}
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/filter/filter.c
^
|
@@ -228,6 +228,9 @@
{
if ((v1.type == T_PATH) && (v2.type == T_PATH_MASK))
return as_path_match(v1.val.ad, v2.val.path_mask);
+ if ((v1.type == T_INT) && (v2.type == T_PATH))
+ return as_path_is_member(v2.val.ad, v1.val.i);
+
if (((v1.type == T_PAIR) || (v1.type == T_QUAD)) && (v2.type == T_CLIST))
return int_set_contains(v2.val.ad, v1.val.i);
#ifndef IPV6
@@ -245,7 +248,7 @@
return ipa_in_net(v1.val.px.ip, v2.val.px.ip, v2.val.px.len);
if ((v1.type == T_PREFIX) && (v2.type == T_PREFIX))
- return ipa_in_net(v1.val.px.ip, v2.val.px.ip, v2.val.px.len) && (v1.val.px.len >= v2.val.px.len);
+ return net_in_net(v1.val.px.ip, v1.val.px.len, v2.val.px.ip, v2.val.px.len);
return CMP_ERROR;
}
@@ -320,28 +323,34 @@
}
static struct adata *
-clist_filter(struct linpool *pool, struct adata *clist, struct f_tree *set, int pos)
+clist_filter(struct linpool *pool, struct adata *list, struct f_val set, int pos)
{
- if (!clist)
+ if (!list)
return NULL;
+ int tree = (set.type == T_SET); /* 1 -> set is T_SET, 0 -> set is T_CLIST */
struct f_val v;
- clist_set_type(set, &v);
+ if (tree)
+ clist_set_type(set.val.t, &v);
+ else
+ v.type = T_PAIR;
- u32 tmp[clist->length/4];
- u32 *l = (u32 *) clist->data;
+ int len = int_set_get_size(list);
+ u32 *l = int_set_get_data(list);
+ u32 tmp[len];
u32 *k = tmp;
- u32 *end = l + clist->length/4;
+ u32 *end = l + len;
while (l < end) {
v.val.i = *l++;
- if (pos == !!find_tree(set, v)) /* pos && find_tree || !pos && !find_tree */
+ /* pos && member(val, set) || !pos && !member(val, set), member() depends on tree */
+ if ((tree ? !!find_tree(set.val.t, v) : int_set_contains(set.val.ad, v.val.i)) == pos)
*k++ = v.val.i;
}
int nl = (k - tmp) * 4;
- if (nl == clist->length)
- return clist;
+ if (nl == list->length)
+ return list;
struct adata *res = adata_empty(pool, nl);
memcpy(res->data, tmp, nl);
@@ -349,11 +358,12 @@
}
static struct adata *
-eclist_filter(struct linpool *pool, struct adata *list, struct f_tree *set, int pos)
+eclist_filter(struct linpool *pool, struct adata *list, struct f_val set, int pos)
{
if (!list)
return NULL;
+ int tree = (set.type == T_SET); /* 1 -> set is T_SET, 0 -> set is T_CLIST */
struct f_val v;
int len = int_set_get_size(list);
@@ -365,7 +375,8 @@
v.type = T_EC;
for (i = 0; i < len; i += 2) {
v.val.ec = ec_get(l, i);
- if (pos == !!find_tree(set, v)) { /* pos && find_tree || !pos && !find_tree */
+ /* pos && member(val, set) || !pos && !member(val, set), member() depends on tree */
+ if ((tree ? !!find_tree(set.val.t, v) : ec_set_contains(set.val.ad, v.val.ec)) == pos) {
*k++ = l[i];
*k++ = l[i+1];
}
@@ -1116,6 +1127,8 @@
#endif
else if ((v2.type == T_SET) && clist_set_type(v2.val.t, &dummy))
arg_set = 1;
+ else if (v2.type == T_CLIST)
+ arg_set = 2;
else
runtime("Can't add/delete non-pair");
@@ -1123,22 +1136,25 @@
switch (what->aux)
{
case 'a':
- if (arg_set)
+ if (arg_set == 1)
runtime("Can't add set");
- res.val.ad = int_set_add(f_pool, v1.val.ad, i);
+ else if (!arg_set)
+ res.val.ad = int_set_add(f_pool, v1.val.ad, i);
+ else
+ res.val.ad = int_set_union(f_pool, v1.val.ad, v2.val.ad);
break;
case 'd':
if (!arg_set)
res.val.ad = int_set_del(f_pool, v1.val.ad, i);
else
- res.val.ad = clist_filter(f_pool, v1.val.ad, v2.val.t, 0);
+ res.val.ad = clist_filter(f_pool, v1.val.ad, v2, 0);
break;
case 'f':
if (!arg_set)
runtime("Can't filter pair");
- res.val.ad = clist_filter(f_pool, v1.val.ad, v2.val.t, 1);
+ res.val.ad = clist_filter(f_pool, v1.val.ad, v2, 1);
break;
default:
@@ -1153,6 +1169,8 @@
/* v2.val is either EC or EC-set */
if ((v2.type == T_SET) && eclist_set_type(v2.val.t))
arg_set = 1;
+ else if (v2.type == T_ECLIST)
+ arg_set = 2;
else if (v2.type != T_EC)
runtime("Can't add/delete non-pair");
@@ -1160,22 +1178,25 @@
switch (what->aux)
{
case 'a':
- if (arg_set)
+ if (arg_set == 1)
runtime("Can't add set");
- res.val.ad = ec_set_add(f_pool, v1.val.ad, v2.val.ec);
+ else if (!arg_set)
+ res.val.ad = ec_set_add(f_pool, v1.val.ad, v2.val.ec);
+ else
+ res.val.ad = ec_set_union(f_pool, v1.val.ad, v2.val.ad);
break;
case 'd':
if (!arg_set)
res.val.ad = ec_set_del(f_pool, v1.val.ad, v2.val.ec);
else
- res.val.ad = eclist_filter(f_pool, v1.val.ad, v2.val.t, 0);
+ res.val.ad = eclist_filter(f_pool, v1.val.ad, v2, 0);
break;
case 'f':
if (!arg_set)
runtime("Can't filter ec");
- res.val.ad = eclist_filter(f_pool, v1.val.ad, v2.val.t, 1);
+ res.val.ad = eclist_filter(f_pool, v1.val.ad, v2, 1);
break;
default:
@@ -1187,6 +1208,38 @@
break;
+ case P('R','C'): /* ROA Check */
+ if (what->arg1)
+ {
+ TWOARGS;
+ if ((v1.type != T_PREFIX) || (v2.type != T_INT))
+ runtime("Invalid argument to roa_check()");
+
+ as = v2.val.i;
+ }
+ else
+ {
+ v1.val.px.ip = (*f_rte)->net->n.prefix;
+ v1.val.px.len = (*f_rte)->net->n.pxlen;
+
+ /* We ignore temporary attributes, probably not a problem here */
+ /* 0x02 is a value of BA_AS_PATH, we don't want to include BGP headers */
+ eattr *e = ea_find((*f_rte)->attrs->eattrs, EA_CODE(EAP_BGP, 0x02));
+
+ if (!e || e->type != EAF_TYPE_AS_PATH)
+ runtime("Missing AS_PATH attribute");
+
+ as_path_get_last(e->u.ptr, &as);
+ }
+
+ struct roa_table_config *rtc = ((struct f_inst_roa_check *) what)->rtc;
+ if (!rtc->table)
+ runtime("Missing ROA table");
+
+ res.type = T_ENUM_ROA;
+ res.val.i = roa_check(rtc->table, v1.val.px.ip, v1.val.px.len, as);
+ break;
+
default:
bug( "Unknown instruction %d (%c)", what->code, what->code & 0xff);
}
@@ -1311,6 +1364,13 @@
case P('C','a'): TWOARGS; break;
case P('a','f'):
case P('a','l'): ONEARG; break;
+ case P('R','C'):
+ TWOARGS;
+ /* Does not really make sense - ROA check resuls may change anyway */
+ if (strcmp(((struct f_inst_roa_check *) f1)->rtc->name,
+ ((struct f_inst_roa_check *) f2)->rtc->name))
+ return 0;
+ break;
default:
bug( "Unknown instruction %d in same (%c)", f1->code, f1->code & 0xff);
}
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/filter/filter.h
^
|
@@ -32,6 +32,12 @@
#define arg1 a1.p
#define arg2 a2.p
+/* Not enough fields in f_inst for three args used by roa_check() */
+struct f_inst_roa_check {
+ struct f_inst i;
+ struct roa_table_config *rtc;
+};
+
struct f_prefix {
ip_addr ip;
int len;
@@ -66,6 +72,8 @@
struct f_inst *f_new_dynamic_attr(int type, int f_type, int code); /* Type as core knows it, type as filters know it, and code of dynamic attribute */
struct f_tree *f_new_tree(void);
struct f_inst *f_generate_complex(int operation, int operation_aux, struct f_inst *dyn, struct f_inst *argument);
+struct f_inst *f_generate_roa_check(struct symbol *sym, struct f_inst *prefix, struct f_inst *asn);
+
struct f_tree *build_tree(struct f_tree *);
struct f_tree *find_tree(struct f_tree *t, struct f_val val);
@@ -141,6 +149,7 @@
#define T_ENUM_SCOPE 0x32
#define T_ENUM_RTC 0x33
#define T_ENUM_RTD 0x34
+#define T_ENUM_ROA 0x35
/* new enums go here */
#define T_ENUM_EMPTY 0x3f /* Special hack for atomic_aggr */
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/filter/test.conf
^
|
@@ -52,12 +52,40 @@
return 15;
}
+roa table rl
+{
+ roa 10.110.0.0/16 max 16 as 1000;
+ roa 10.120.0.0/16 max 24 as 1000;
+ roa 10.130.0.0/16 max 24 as 2000;
+ roa 10.130.128.0/18 max 24 as 3000;
+}
+
+function test_roa()
+{
+ # cannot be tested in __startup(), sorry
+ print "Testing ROA";
+ print "Should be true: ", roa_check(rl, 10.10.0.0/16, 1000) = ROA_UNKNOWN,
+ " ", roa_check(rl, 10.0.0.0/8, 1000) = ROA_UNKNOWN,
+ " ", roa_check(rl, 10.110.0.0/16, 1000) = ROA_VALID,
+ " ", roa_check(rl, 10.110.0.0/16, 2000) = ROA_INVALID,
+ " ", roa_check(rl, 10.110.32.0/20, 1000) = ROA_INVALID,
+ " ", roa_check(rl, 10.120.32.0/20, 1000) = ROA_VALID;
+ print "Should be true: ", roa_check(rl, 10.120.32.0/20, 2000) = ROA_INVALID,
+ " ", roa_check(rl, 10.120.32.32/28, 1000) = ROA_INVALID,
+ " ", roa_check(rl, 10.130.130.0/24, 1000) = ROA_INVALID,
+ " ", roa_check(rl, 10.130.130.0/24, 2000) = ROA_VALID,
+ " ", roa_check(rl, 10.130.30.0/24, 3000) = ROA_INVALID,
+ " ", roa_check(rl, 10.130.130.0/24, 3000) = ROA_VALID;
+}
+
function paths()
bgpmask pm1;
bgpmask pm2;
bgppath p2;
clist l;
+clist l2;
eclist el;
+eclist el2;
{
pm1 = / 4 3 2 1 /;
pm2 = [= 4 3 2 1 =];
@@ -67,10 +95,10 @@
p2 = prepend( p2, 3 );
p2 = prepend( p2, 4 );
print "Testing paths: ", p2;
- print "Should be true: ", p2 ~ pm1, " ", p2 ~ pm2;
+ print "Should be true: ", p2 ~ pm1, " ", p2 ~ pm2, " ", 3 ~ p2;
print "4 = ", p2.len;
p2 = prepend( p2, 5 );
- print "Should be false: ", p2 ~ pm1, " ", p2 ~ pm2;
+ print "Should be false: ", p2 ~ pm1, " ", p2 ~ pm2, " ", 10 ~ p2;
print "Should be true: ", p2 ~ / ? 4 3 2 1 /, " ", p2, " ", / ? 4 3 2 1 /;
print "Should be true: ", p2 ~ [= * 4 3 * 1 =], " ", p2, " ", [= * 4 3 * 1 =];
print "Should be true: ", p2 ~ [= (3+2) (2*2) 3 2 1 =], " ", p2 ~ mkpath(5, 4);
@@ -108,6 +136,7 @@
l = add( l, (3,3) );
l = add( l, (3,4) );
l = add( l, (3,5) );
+ l2 = filter( l, [(3,*)] );
l = delete( l, [(3,2..4)] );
print "Community list (1,2) (3,1) (3,5) ", l;
l = add( l, (3,2) );
@@ -120,6 +149,14 @@
print "Community list (3,1) ", l;
l = delete( l, [(*,(onef(5)))] );
print "Community list empty ", l;
+ l2 = add( l2, (3,6) );
+ l = filter( l2, [(3,1..4)] );
+ l2 = filter( l2, [(3,3..6)] );
+ print "clist A (1..4): ", l;
+ print "clist B (3..6): ", l2;
+ print "clist A union B: ", add( l2, l );
+ print "clist A isect B: ", filter( l, l2 );
+ print "clist A \ B: ", delete( l, l2 );
el = -- empty --;
el = add(el, (rt, 10, 20));
@@ -143,6 +180,16 @@
print "EC list (rt, 10, 1) (rt, 10, 30): ", el;
print "Testing EC list, true: ", (rt, 10, 1) ~ el, " ", el ~ [(rt, 10, ten..40)];
print "Testing EC list, false: ", (rt, 10, 20) ~ el, " ", (ro, 10.20.30.40, 100) ~ el, " ", el ~ [(rt, 10, 35..40)], " ", el ~ [(ro, 10, *)];
+ el = add(el, (rt, 10, 40));
+ el2 = filter(el, [(rt, 10, 20..40)] );
+ el2 = add(el2, (rt, 10, 50));
+ print "eclist A (1,30,40): ", el;
+ print "eclist B (30,40,50): ", el2;
+ print "eclist A union B: ", add( el2, el );
+ print "eclist A isect B: ", filter( el, el2 );
+ print "eclist A \ B: ", delete( el, el2 );
+
+# test_roa();
}
function bla()
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/lib/ip.h
^
|
@@ -15,7 +15,10 @@
#include "ipv6.h"
#endif
-#define ipa_in_net(x,n,p) (!ipa_nonzero(ipa_and(ipa_xor((n),(x)),ipa_mkmask(p))))
+#define ipa_zero(x) (!ipa_nonzero(x))
+#define ip_is_prefix(a,l) (!ipa_nonzero(ipa_and(a, ipa_not(ipa_mkmask(l)))))
+#define ipa_in_net(x,n,p) (ipa_zero(ipa_and(ipa_xor((n),(x)),ipa_mkmask(p))))
+#define net_in_net(n1,l1,n2,l2) (((l1) >= (l2)) && (ipa_zero(ipa_and(ipa_xor((n1),(n2)),ipa_mkmask(l2)))))
/*
* ip_classify() returns either a negative number for invalid addresses
@@ -50,9 +53,6 @@
unsigned int len;
};
-#define ip_is_prefix(a,l) (!ipa_nonzero(ipa_and(a, ipa_not(ipa_mkmask(l)))))
-#define ipa_zero(x) (!ipa_nonzero(x))
-
static inline int ipa_classify_net(ip_addr a)
{ return ipa_zero(a) ? (IADDR_HOST | SCOPE_UNIVERSE) : ipa_classify(a); }
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/nest/Makefile
^
|
@@ -1,4 +1,4 @@
-source=rt-table.c rt-fib.c rt-attr.c proto.c iface.c rt-dev.c password.c cli.c locks.c cmds.c neighbor.c \
+source=rt-table.c rt-fib.c rt-attr.c rt-roa.c proto.c iface.c rt-dev.c password.c cli.c locks.c cmds.c neighbor.c \
a-path.c a-set.c
root-rel=../
dir-name=nest
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/nest/a-set.c
^
|
@@ -264,3 +264,67 @@
return res;
}
+
+
+struct adata *
+int_set_union(struct linpool *pool, struct adata *l1, struct adata *l2)
+{
+ if (!l1)
+ return l2;
+ if (!l2)
+ return l1;
+
+ struct adata *res;
+ int len = int_set_get_size(l2);
+ u32 *l = int_set_get_data(l2);
+ u32 tmp[len];
+ u32 *k = tmp;
+ int i;
+
+ for (i = 0; i < len; i++)
+ if (!int_set_contains(l1, l[i]))
+ *k++ = l[i];
+
+ if (k == tmp)
+ return l1;
+
+ len = (k - tmp) * 4;
+ res = lp_alloc(pool, sizeof(struct adata) + l1->length + len);
+ res->length = l1->length + len;
+ memcpy(res->data, l1->data, l1->length);
+ memcpy(res->data + l1->length, tmp, len);
+ return res;
+}
+
+struct adata *
+ec_set_union(struct linpool *pool, struct adata *l1, struct adata *l2)
+{
+ if (!l1)
+ return l2;
+ if (!l2)
+ return l1;
+
+ struct adata *res;
+ int len = int_set_get_size(l2);
+ u32 *l = int_set_get_data(l2);
+ u32 tmp[len];
+ u32 *k = tmp;
+ int i;
+
+ for (i = 0; i < len; i += 2)
+ if (!ec_set_contains(l1, ec_get(l, i)))
+ {
+ *k++ = l[i];
+ *k++ = l[i+1];
+ }
+
+ if (k == tmp)
+ return l1;
+
+ len = (k - tmp) * 4;
+ res = lp_alloc(pool, sizeof(struct adata) + l1->length + len);
+ res->length = l1->length + len;
+ memcpy(res->data, l1->data, l1->length);
+ memcpy(res->data + l1->length, tmp, len);
+ return res;
+}
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/nest/attrs.h
^
|
@@ -96,6 +96,8 @@
struct adata *ec_set_add(struct linpool *pool, struct adata *list, u64 val);
struct adata *int_set_del(struct linpool *pool, struct adata *list, u32 val);
struct adata *ec_set_del(struct linpool *pool, struct adata *list, u64 val);
+struct adata *int_set_union(struct linpool *pool, struct adata *l1, struct adata *l2);
+struct adata *ec_set_union(struct linpool *pool, struct adata *l1, struct adata *l2);
#endif
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/nest/cmds.c
^
|
@@ -7,6 +7,7 @@
*/
#include "nest/bird.h"
+#include "nest/route.h"
#include "nest/cli.h"
#include "conf/conf.h"
#include "nest/cmds.h"
@@ -35,16 +36,22 @@
}
void
-cmd_show_symbols(struct symbol *sym)
+cmd_show_symbols(struct sym_show_data *sd)
{
int pos = 0;
+ struct symbol *sym = sd->sym;
if (sym)
- cli_msg(1010, "%s\t%s", sym->name, cf_symbol_class_name(sym));
+ cli_msg(1010, "%-8s\t%s", sym->name, cf_symbol_class_name(sym));
else
{
while (sym = cf_walk_symbols(config, sym, &pos))
- cli_msg(-1010, "%s\t%s", sym->name, cf_symbol_class_name(sym));
+ {
+ if (sd->type && (sym->class != sd->type))
+ continue;
+
+ cli_msg(-1010, "%-8s\t%s", sym->name, cf_symbol_class_name(sym));
+ }
cli_msg(0, "");
}
}
@@ -65,6 +72,7 @@
extern pool *rt_table_pool;
extern pool *rta_pool;
+extern pool *roa_pool;
extern pool *proto_pool;
void
@@ -73,6 +81,7 @@
cli_msg(-1018, "BIRD memory usage");
print_size("Routing tables:", rmemsize(rt_table_pool));
print_size("Route attributes:", rmemsize(rta_pool));
+ print_size("ROA tables:", rmemsize(roa_pool));
print_size("Protocols:", rmemsize(proto_pool));
print_size("Total:", rmemsize(&root_pool));
cli_msg(0, "");
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/nest/cmds.h
^
|
@@ -6,6 +6,11 @@
* Can be freely distributed and used under the terms of the GNU GPL.
*/
+struct sym_show_data {
+ int type; /* Symbols type to show */
+ struct symbol *sym;
+};
+
void cmd_show_status(void);
-void cmd_show_symbols(struct symbol *sym);
+void cmd_show_symbols(struct sym_show_data *sym);
void cmd_show_memory(void);
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/nest/config.Y
^
|
@@ -19,6 +19,7 @@
static struct proto_config *this_proto;
static struct iface_patt *this_ipatt;
static struct iface_patt_node *this_ipn;
+static struct roa_table_config *this_roa_table;
static list *this_p_list;
static struct password_item *this_p_item;
static int password_id;
@@ -44,7 +45,7 @@
CF_KEYWORDS(ROUTER, ID, PROTOCOL, TEMPLATE, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT)
CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, TABLE, STATES, ROUTES, FILTERS)
CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES)
-CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREEXPORT, GENERATE)
+CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREEXPORT, GENERATE, ROA, MAX, FLUSH)
CF_KEYWORDS(LISTEN, BGP, V6ONLY, DUAL, ADDRESS, PORT, PASSWORDS, DESCRIPTION)
CF_KEYWORDS(RELOAD, IN, OUT, MRTDUMP, MESSAGES, RESTRICT, MEMORY, IGP_METRIC)
@@ -53,13 +54,17 @@
CF_ENUM(T_ENUM_SCOPE, SCOPE_, HOST, LINK, SITE, ORGANIZATION, UNIVERSE, UNDEFINED)
CF_ENUM(T_ENUM_RTC, RTC_, UNICAST, BROADCAST, MULTICAST, ANYCAST)
CF_ENUM(T_ENUM_RTD, RTD_, ROUTER, DEVICE, BLACKHOLE, UNREACHABLE, PROHIBIT, MULTIPATH)
+CF_ENUM(T_ENUM_ROA, ROA_, UNKNOWN, VALID, INVALID)
%type <i32> idval
%type <f> imexport
%type <r> rtable
%type <s> optsym
%type <ra> r_args
-%type <i> proto_start echo_mask echo_size debug_mask debug_list debug_flag mrtdump_mask mrtdump_list mrtdump_flag export_or_preexport
+%type <ro> roa_args
+%type <rot> roa_table_arg
+%type <sd> sym_args
+%type <i> proto_start echo_mask echo_size debug_mask debug_list debug_flag mrtdump_mask mrtdump_list mrtdump_flag export_or_preexport roa_mode
%type <ps> proto_patt proto_patt2
CF_GRAMMAR
@@ -112,6 +117,24 @@
}
;
+CF_ADDTO(conf, roa_table)
+
+roa_table_start: ROA TABLE SYM {
+ this_roa_table = roa_new_table_config($3);
+};
+
+roa_table_opts:
+ /* empty */
+ | roa_table_opts ROA prefix MAX NUM AS NUM ';' {
+ roa_add_item_config(this_roa_table, $3.addr, $3.len, $5, $7);
+ }
+ ;
+
+roa_table:
+ roa_table_start
+ | roa_table_start '{' roa_table_opts '}'
+ ;
+
/* Definition of protocols */
CF_ADDTO(conf, proto)
@@ -219,7 +242,6 @@
dev_proto_start: proto_start DIRECT {
this_proto = proto_config_new(&proto_device, sizeof(struct rt_dev_config), $1);
- this_proto->preference = DEF_PREF_DIRECT;
init_list(&DIRECT_CFG->iface_list);
}
;
@@ -354,6 +376,7 @@
CF_CLI(SHOW INTERFACES SUMMARY,,, [[Show summary of network interfaces]])
{ if_show_summary(); } ;
+CF_CLI_HELP(SHOW ROUTE, ..., [[Show routing table]])
CF_CLI(SHOW ROUTE, r_args, [[[<prefix>|for <prefix>|for <ip>] [table <t>] [filter <f>|where <cond>] [all] [primary] [(export|preexport) <p>] [protocol <p>] [stats|count]]], [[Show routing table]])
{ rt_show($3); } ;
@@ -433,9 +456,97 @@
| EXPORT { $$ = 2; }
;
-CF_CLI(SHOW SYMBOLS, optsym, [<symbol>], [[Show all known symbolic names]])
+
+CF_CLI_HELP(SHOW ROA, ..., [[Show ROA table]])
+CF_CLI(SHOW ROA, roa_args, [<prefix> | in <prefix> | for <prefix>] [as <num>] [table <t>], [[Show ROA table]])
+{ roa_show($3); } ;
+
+roa_args:
+ /* empty */ {
+ $$ = cfg_allocz(sizeof(struct roa_show_data));
+ $$->mode = ROA_SHOW_ALL;
+ $$->table = roa_table_default;
+ if (roa_table_default == NULL)
+ cf_error("No ROA table defined");
+ }
+ | roa_args roa_mode prefix {
+ $$ = $1;
+ if ($$->mode != ROA_SHOW_ALL) cf_error("Only one prefix expected");
+ $$->prefix = $3.addr;
+ $$->pxlen = $3.len;
+ $$->mode = $2;
+ }
+ | roa_args AS NUM {
+ $$ = $1;
+ $$->asn = $3;
+ }
+ | roa_args TABLE SYM {
+ $$ = $1;
+ if ($3->class != SYM_ROA) cf_error("%s is not a ROA table", $3->name);
+ $$->table = ((struct roa_table_config *)$3->def)->table;
+ }
+ ;
+
+roa_mode:
+ { $$ = ROA_SHOW_PX; }
+ | IN { $$ = ROA_SHOW_IN; }
+ | FOR { $$ = ROA_SHOW_FOR; }
+ ;
+
+
+CF_CLI_HELP(SHOW SYMBOLS, ..., [[Show all known symbolic names]])
+CF_CLI(SHOW SYMBOLS, sym_args, [table|filter|function|protocol|template|roa|<symbol>], [[Show all known symbolic names]])
{ cmd_show_symbols($3); } ;
+sym_args:
+ /* empty */ {
+ $$ = cfg_allocz(sizeof(struct sym_show_data));
+ }
+ | sym_args TABLE { $$ = $1; $$->type = SYM_TABLE; }
+ | sym_args FUNCTION { $$ = $1; $$->type = SYM_FUNCTION; }
+ | sym_args FILTER { $$ = $1; $$->type = SYM_FILTER; }
+ | sym_args PROTOCOL { $$ = $1; $$->type = SYM_PROTO; }
+ | sym_args TEMPLATE { $$ = $1; $$->type = SYM_TEMPLATE; }
+ | sym_args ROA { $$ = $1; $$->type = SYM_ROA; }
+ | sym_args SYM { $$ = $1; $$->sym = $2; }
+ ;
+
+
+roa_table_arg:
+ /* empty */ {
+ if (roa_table_default == NULL)
+ cf_error("No ROA table defined");
+ $$ = roa_table_default;
+ }
+ | TABLE SYM {
+ if ($2->class != SYM_ROA)
+ cf_error("%s is not a ROA table", $2->name);
+ $$ = ((struct roa_table_config *)$2->def)->table;
+ }
+ ;
+
+CF_CLI_HELP(ADD, roa ..., [[Add ROA record]])
+CF_CLI(ADD ROA, prefix MAX NUM AS NUM roa_table_arg, <prefix> max <num> as <num> [table <name>], [[Add ROA record]])
+{
+ if (! cli_access_restricted())
+ { roa_add_item($8, $3.addr, $3.len, $5, $7, ROA_SRC_DYNAMIC); cli_msg(0, ""); }
+};
+
+CF_CLI_HELP(DELETE, roa ..., [[Delete ROA record]])
+CF_CLI(DELETE ROA, prefix MAX NUM AS NUM roa_table_arg, <prefix> max <num> as <num> [table <name>], [[Delete ROA record]])
+{
+ if (! cli_access_restricted())
+ { roa_delete_item($8, $3.addr, $3.len, $5, $7, ROA_SRC_DYNAMIC); cli_msg(0, ""); }
+};
+
+CF_CLI_HELP(FLUSH, roa [table <name>], [[Removes all dynamic ROA records]])
+CF_CLI(FLUSH ROA, roa_table_arg, [table <name>], [[Removes all dynamic ROA records]])
+{
+ if (! cli_access_restricted())
+ { roa_flush($3, ROA_SRC_DYNAMIC); cli_msg(0, ""); }
+};
+
+
CF_CLI_HELP(DUMP, ..., [[Dump debugging information]])
CF_CLI(DUMP RESOURCES,,, [[Dump all allocated resource]])
{ rdump(&root_pool); cli_msg(0, ""); } ;
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/nest/iface.c
^
|
@@ -253,6 +253,24 @@
}
/**
+ * if_delete - remove interface
+ * @old: interface
+ *
+ * This function is called by the low-level platform dependent code
+ * whenever it notices an interface disappears. It is just a shorthand
+ * for if_update().
+ */
+
+void
+if_delete(struct iface *old)
+{
+ struct iface f = {};
+ strncpy(f.name, old->name, sizeof(f.name)-1);
+ f.flags = IF_SHUTDOWN;
+ if_update(&f);
+}
+
+/**
* if_update - update interface status
* @new: new interface status
*
@@ -288,13 +306,14 @@
new->addr = i->addr;
memcpy(&new->addrs, &i->addrs, sizeof(i->addrs));
memcpy(i, new, sizeof(*i));
+ i->flags &= ~IF_UP; /* IF_TMP_DOWN will be added later */
goto newif;
}
- else if (c)
- {
- if_copy(i, new);
- if_notify_change(c, i);
- }
+
+ if_copy(i, new);
+ if (c)
+ if_notify_change(c, i);
+
i->flags |= IF_UPDATED;
return i;
}
@@ -400,7 +419,7 @@
struct iface *i;
WALK_LIST(i, iface_list)
- if (i->index == idx)
+ if (i->index == idx && !(i->flags & IF_SHUTDOWN))
return i;
return NULL;
}
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/nest/iface.h
^
|
@@ -88,6 +88,7 @@
void if_show(void);
void if_show_summary(void);
struct iface *if_update(struct iface *);
+void if_delete(struct iface *old);
struct ifa *ifa_update(struct ifa *);
void ifa_delete(struct ifa *);
void if_start_update(void);
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/nest/proto.c
^
|
@@ -200,6 +200,7 @@
c->global = new_config;
c->protocol = pr;
c->name = pr->name;
+ c->preference = pr->preference;
c->class = class;
c->out_filter = FILTER_REJECT;
c->table = c->global->master_rtc;
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/nest/protocol.h
^
|
@@ -39,6 +39,7 @@
char *template; /* Template for automatic generation of names */
int name_counter; /* Counter for automatic name generation */
int attr_class; /* Attribute class known to this protocol */
+ unsigned preference; /* Default protocol preference */
void (*preconfig)(struct protocol *, struct config *); /* Just before configuring */
void (*postconfig)(struct proto_config *); /* After configuring each instance */
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/nest/route.h
^
|
@@ -454,4 +454,84 @@
#define DEF_PREF_PIPE 70 /* Routes piped from other tables */
#define DEF_PREF_INHERITED 10 /* Routes inherited from other routing daemons */
+
+/*
+ * Route Origin Authorization
+ */
+
+struct roa_item {
+ u32 asn;
+ byte maxlen;
+ byte src;
+ struct roa_item *next;
+};
+
+struct roa_node {
+ struct fib_node n;
+ struct roa_item *items;
+ // u32 cached_asn;
+};
+
+struct roa_table {
+ node n; /* Node in roa_table_list */
+ struct fib fib;
+ char *name; /* Name of this ROA table */
+ struct roa_table_config *cf; /* Configuration of this ROA table */
+};
+
+struct roa_item_config {
+ ip_addr prefix;
+ byte pxlen, maxlen;
+ u32 asn;
+ struct roa_item_config *next;
+};
+
+struct roa_table_config {
+ node n; /* Node in config->rpa_tables */
+ char *name; /* Name of this ROA table */
+ struct roa_table *table;
+
+ struct roa_item_config *roa_items; /* Preconfigured ROA items */
+
+ // char *filename;
+ // int gc_max_ops; /* Maximum number of operations before GC is run */
+ // int gc_min_time; /* Minimum time between two consecutive GC runs */
+};
+
+struct roa_show_data {
+ struct fib_iterator fit;
+ struct roa_table *table;
+ ip_addr prefix;
+ byte pxlen;
+ byte mode; /* ROA_SHOW_* values */
+ u32 asn; /* Filter ASN, 0 -> all */
+};
+
+#define ROA_UNKNOWN 0
+#define ROA_VALID 1
+#define ROA_INVALID 2
+
+#define ROA_SRC_ANY 0
+#define ROA_SRC_CONFIG 1
+#define ROA_SRC_DYNAMIC 2
+
+#define ROA_SHOW_ALL 0
+#define ROA_SHOW_PX 1
+#define ROA_SHOW_IN 2
+#define ROA_SHOW_FOR 3
+
+extern struct roa_table *roa_table_default;
+
+void roa_add_item(struct roa_table *t, ip_addr prefix, byte pxlen, byte maxlen, u32 asn, byte src);
+void roa_delete_item(struct roa_table *t, ip_addr prefix, byte pxlen, byte maxlen, u32 asn, byte src);
+void roa_flush(struct roa_table *t, byte src);
+byte roa_check(struct roa_table *t, ip_addr prefix, byte pxlen, u32 asn);
+struct roa_table_config * roa_new_table_config(struct symbol *s);
+void roa_add_item_config(struct roa_table_config *rtc, ip_addr prefix, byte pxlen, byte maxlen, u32 asn);
+void roa_init(void);
+void roa_preconfig(struct config *c);
+void roa_commit(struct config *new, struct config *old);
+void roa_show(struct roa_show_data *d);
+
+
#endif
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/nest/rt-dev.c
^
|
@@ -109,6 +109,7 @@
struct protocol proto_device = {
name: "Direct",
template: "direct%d",
+ preference: DEF_PREF_DIRECT,
init: dev_init,
reconfigure: dev_reconfigure,
copy_config: dev_copy_config
|
[-]
[+]
|
Added |
bird-1.3.7.tar.bz2/nest/rt-roa.c
^
|
@@ -0,0 +1,440 @@
+/*
+ * BIRD -- Route Origin Authorization
+ *
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#undef LOCAL_DEBUG
+
+#include "nest/bird.h"
+#include "nest/route.h"
+#include "nest/cli.h"
+#include "lib/lists.h"
+#include "lib/resource.h"
+#include "lib/event.h"
+#include "lib/string.h"
+#include "conf/conf.h"
+
+
+pool *roa_pool;
+static slab *roa_slab; /* Slab of struct roa_item */
+static list roa_table_list; /* List of struct roa_table */
+struct roa_table *roa_table_default; /* The first ROA table in the config */
+
+static inline int
+src_match(struct roa_item *it, byte src)
+{ return !src || it->src == src; }
+
+/**
+ * roa_add_item - add a ROA entry
+ * @t: ROA table
+ * @prefix: prefix of the ROA entry
+ * @pxlen: prefix length of the ROA entry
+ * @maxlen: max length field of the ROA entry
+ * @asn: AS number field of the ROA entry
+ * @src: source of the ROA entry (ROA_SRC_*)
+ *
+ * The function adds a new ROA entry to the ROA table. If the same ROA
+ * is already in the table, nothing is added. @src field is used to
+ * distinguish different sources of ROAs.
+ */
+void
+roa_add_item(struct roa_table *t, ip_addr prefix, byte pxlen, byte maxlen, u32 asn, byte src)
+{
+ struct roa_node *n = fib_get(&t->fib, &prefix, pxlen);
+
+ // if ((n->items == NULL) && (n->n.x0 != ROA_INVALID))
+ // t->cached_items--;
+
+ struct roa_item *it;
+ for (it = n->items; it; it = it->next)
+ if ((it->maxlen == maxlen) && (it->asn == asn) && src_match(it, src))
+ return;
+
+ it = sl_alloc(roa_slab);
+ it->asn = asn;
+ it->maxlen = maxlen;
+ it->src = src;
+ it->next = n->items;
+ n->items = it;
+}
+
+/**
+ * roa_delete_item - delete a ROA entry
+ * @t: ROA table
+ * @prefix: prefix of the ROA entry
+ * @pxlen: prefix length of the ROA entry
+ * @maxlen: max length field of the ROA entry
+ * @asn: AS number field of the ROA entry
+ * @src: source of the ROA entry (ROA_SRC_*)
+ *
+ * The function removes a specified ROA entry from the ROA table and
+ * frees it. If @src field is not ROA_SRC_ANY, only entries from
+ * that source are considered.
+ */
+void
+roa_delete_item(struct roa_table *t, ip_addr prefix, byte pxlen, byte maxlen, u32 asn, byte src)
+{
+ struct roa_node *n = fib_find(&t->fib, &prefix, pxlen);
+
+ if (!n)
+ return;
+
+ struct roa_item *it, **itp;
+ for (itp = &n->items; it = *itp; itp = &it->next)
+ if ((it->maxlen == maxlen) && (it->asn == asn) && src_match(it, src))
+ break;
+
+ if (!it)
+ return;
+
+ *itp = it->next;
+ sl_free(roa_slab, it);
+
+ // if ((n->items == NULL) && (n->n.x0 != ROA_INVALID))
+ // t->cached_items++;
+}
+
+
+/**
+ * roa_flush - flush a ROA table
+ * @t: ROA table
+ * @src: source of ROA entries (ROA_SRC_*)
+ *
+ * The function removes and frees ROA entries from the ROA table. If
+ * @src is ROA_SRC_ANY, all entries in the table are removed,
+ * otherwise only all entries from that source are removed.
+ */
+void
+roa_flush(struct roa_table *t, byte src)
+{
+ struct roa_item *it, **itp;
+ struct roa_node *n;
+
+ FIB_WALK(&t->fib, fn)
+ {
+ n = (struct roa_node *) fn;
+
+ itp = &n->items;
+ while (it = *itp)
+ if (src_match(it, src))
+ {
+ *itp = it->next;
+ sl_free(roa_slab, it);
+ }
+ else
+ itp = &it->next;
+ }
+ FIB_WALK_END;
+
+ // TODO add cleanup of roa_nodes
+}
+
+
+
+/*
+byte
+roa_check(struct roa_table *t, ip_addr prefix, byte pxlen, u32 asn)
+{
+ struct roa_node *n = fib_find(&t->fib, &prefix, pxlen);
+
+ if (n && n->n.x0 == ROA_UNKNOWN)
+ return ROA_UNKNOWN;
+
+ if (n && n->n.x0 == ROA_VALID && asn == n->cached_asn)
+ return ROA_VALID;
+
+ byte rv = roa_match(t, n, prefix, pxlen, asn);
+
+ if (rv != ROA_INVALID)
+ {
+ if (!n)
+ {
+ if (t->cached_items >= t->cached_items_max)
+ n = fib_get(&t->fib, &prefix, pxlen);
+ t->cached_items++;
+ }
+
+ n->cached_asn = asn;
+ n->n.x0 = rv;
+ }
+
+ return rv;
+}
+*/
+
+/**
+ * roa_check - check validity of route origination in a ROA table
+ * @t: ROA table
+ * @prefix: network prefix to check
+ * @pxlen: length of network prefix
+ * @asn: AS number of network prefix
+ *
+ * Implements RFC 6483 route validation for the given network
+ * prefix. The procedure is to find all candidate ROAs - ROAs whose
+ * prefixes cover the give network prefix. If there is no candidate
+ * ROA, return ROA_UNKNOWN. If there is a candidate ROA with matching
+ * ASN and maxlen field greater than or equal to the given prefix
+ * length, return ROA_VALID. Otherwise return ROA_INVALID. If caller
+ * cannot determine origin AS, 0 could be used (in that case ROA_VALID
+ * cannot happen).
+ */
+byte
+roa_check(struct roa_table *t, ip_addr prefix, byte pxlen, u32 asn)
+{
+ struct roa_node *n;
+ ip_addr px;
+ byte anything = 0;
+
+ int len;
+ for (len = pxlen; len >= 0; len--)
+ {
+ px = ipa_and(prefix, ipa_mkmask(len));
+ n = fib_find(&t->fib, &px, len);
+
+ if (!n)
+ continue;
+
+ struct roa_item *it;
+ for (it = n->items; it; it = it->next)
+ {
+ anything = 1;
+ if ((it->maxlen >= pxlen) && (it->asn == asn) && asn)
+ return ROA_VALID;
+ }
+ }
+
+ return anything ? ROA_INVALID : ROA_UNKNOWN;
+}
+
+static void
+roa_node_init(struct fib_node *fn)
+{
+ struct roa_node *n = (struct roa_node *) fn;
+ n->items = NULL;
+}
+
+static inline void
+roa_populate(struct roa_table *t)
+{
+ struct roa_item_config *ric;
+ for (ric = t->cf->roa_items; ric; ric = ric->next)
+ roa_add_item(t, ric->prefix, ric->pxlen, ric->maxlen, ric->asn, ROA_SRC_CONFIG);
+}
+
+static void
+roa_new_table(struct roa_table_config *cf)
+{
+ struct roa_table *t;
+
+ t = mb_allocz(roa_pool, sizeof(struct roa_table));
+ fib_init(&t->fib, roa_pool, sizeof(struct roa_node), 0, roa_node_init);
+ t->name = cf->name;
+ t->cf = cf;
+
+ cf->table = t;
+ add_tail(&roa_table_list, &t->n);
+
+ roa_populate(t);
+}
+
+struct roa_table_config *
+roa_new_table_config(struct symbol *s)
+{
+ struct roa_table_config *rtc = cfg_allocz(sizeof(struct roa_table_config));
+
+ cf_define_symbol(s, SYM_ROA, rtc);
+ rtc->name = s->name;
+ add_tail(&new_config->roa_tables, &rtc->n);
+ return rtc;
+}
+
+/**
+ * roa_add_item_config - add a static ROA entry to a ROA table configuration
+ *
+ * Arguments are self-explanatory. The first is the ROA table config, rest
+ * are specifying the ROA entry.
+ */
+void
+roa_add_item_config(struct roa_table_config *rtc, ip_addr prefix, byte pxlen, byte maxlen, u32 asn)
+{
+ struct roa_item_config *ric = cfg_allocz(sizeof(struct roa_item_config));
+
+ ric->prefix = prefix;
+ ric->pxlen = pxlen;
+ ric->maxlen = maxlen;
+ ric->asn = asn;
+ ric->next = rtc->roa_items;
+ rtc->roa_items = ric;
+}
+
+/**
+ * roa_init - initialize ROA tables
+ *
+ * This function is called during BIRD startup. It initializes
+ * the ROA table module.
+ */
+void
+roa_init(void)
+{
+ roa_pool = rp_new(&root_pool, "ROA tables");
+ roa_slab = sl_new(roa_pool, sizeof(struct roa_item));
+ init_list(&roa_table_list);
+}
+
+void
+roa_preconfig(struct config *c)
+{
+ init_list(&c->roa_tables);
+}
+
+
+/**
+ * roa_commit - commit new ROA table configuration
+ * @new: new configuration
+ * @old: original configuration or %NULL if it's boot time config
+ *
+ * Scan differences between @old and @new configuration and modify the
+ * ROA tables according to these changes. If @new defines a previously
+ * unknown table, create it, if it omits a table existing in @old,
+ * delete it (there are no references, only indirect through struct
+ * roa_table_config). If it exists in both configurations, update the
+ * configured ROA entries.
+ */
+void
+roa_commit(struct config *new, struct config *old)
+{
+ struct roa_table_config *cf;
+ struct roa_table *t;
+
+ if (old)
+ WALK_LIST(t, roa_table_list)
+ {
+ struct symbol *sym = cf_find_symbol(t->name);
+ if (sym && sym->class == SYM_ROA)
+ {
+ /* Found old table in new config */
+ cf = sym->def;
+ cf->table = t;
+ t->name = cf->name;
+ t->cf = cf;
+
+ /* Reconfigure it */
+ roa_flush(t, ROA_SRC_CONFIG);
+ roa_populate(t);
+ }
+ else
+ {
+ t->cf->table = NULL;
+
+ /* Free it now */
+ roa_flush(t, ROA_SRC_ANY);
+ rem_node(&t->n);
+ fib_free(&t->fib);
+ mb_free(t);
+ }
+ }
+
+ /* Add new tables */
+ WALK_LIST(cf, new->roa_tables)
+ if (! cf->table)
+ roa_new_table(cf);
+
+ roa_table_default = EMPTY_LIST(new->roa_tables) ? NULL :
+ ((struct roa_table_config *) HEAD(new->roa_tables))->table;
+}
+
+
+
+static void
+roa_show_node(struct cli *c, struct roa_node *rn, int len, u32 asn)
+{
+ struct roa_item *ri;
+
+ for (ri = rn->items; ri; ri = ri->next)
+ if ((ri->maxlen >= len) && (!asn || (ri->asn == asn)))
+ cli_printf(c, -1019, "%I/%d max %d as %u", rn->n.prefix, rn->n.pxlen, ri->maxlen, ri->asn);
+}
+
+static void
+roa_show_cont(struct cli *c)
+{
+ struct roa_show_data *d = c->rover;
+ struct fib *fib = &d->table->fib;
+ struct fib_iterator *it = &d->fit;
+ struct roa_node *rn;
+ unsigned max = 32;
+
+ FIB_ITERATE_START(fib, it, f)
+ {
+ rn = (struct roa_node *) f;
+
+ if (!max--)
+ {
+ FIB_ITERATE_PUT(it, f);
+ return;
+ }
+
+ if ((d->mode == ROA_SHOW_ALL) ||
+ net_in_net(rn->n.prefix, rn->n.pxlen, d->prefix, d->pxlen))
+ roa_show_node(c, rn, 0, d->asn);
+ }
+ FIB_ITERATE_END(f);
+
+ cli_printf(c, 0, "");
+ c->cont = c->cleanup = NULL;
+}
+
+static void
+roa_show_cleanup(struct cli *c)
+{
+ struct roa_show_data *d = c->rover;
+
+ /* Unlink the iterator */
+ fit_get(&d->table->fib, &d->fit);
+}
+
+void
+roa_show(struct roa_show_data *d)
+{
+ struct roa_node *rn;
+ ip_addr px;
+ int len;
+
+ switch (d->mode)
+ {
+ case ROA_SHOW_ALL:
+ case ROA_SHOW_IN:
+ FIB_ITERATE_INIT(&d->fit, &d->table->fib);
+ this_cli->cont = roa_show_cont;
+ this_cli->cleanup = roa_show_cleanup;
+ this_cli->rover = d;
+ break;
+
+ case ROA_SHOW_PX:
+ rn = fib_find(&d->table->fib, &d->prefix, d->pxlen);
+ if (rn)
+ {
+ roa_show_node(this_cli, rn, 0, d->asn);
+ cli_msg(0, "");
+ }
+ else
+ cli_msg(-8001, "Network not in table");
+ break;
+
+ case ROA_SHOW_FOR:
+ for (len = d->pxlen; len >= 0; len--)
+ {
+ px = ipa_and(d->prefix, ipa_mkmask(len));
+ rn = fib_find(&d->table->fib, &px, len);
+
+ if (!rn)
+ continue;
+
+ roa_show_node(this_cli, rn, 0, d->asn);
+ }
+ cli_msg(0, "");
+ break;
+ }
+}
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/proto/bgp/bgp.c
^
|
@@ -1178,6 +1178,7 @@
name: "BGP",
template: "bgp%d",
attr_class: EAP_BGP,
+ preference: DEF_PREF_BGP,
init: bgp_init,
start: bgp_start,
shutdown: bgp_shutdown,
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/proto/bgp/config.Y
^
|
@@ -33,7 +33,6 @@
bgp_proto_start: proto_start BGP {
this_proto = proto_config_new(&proto_bgp, sizeof(struct bgp_config), $1);
- this_proto->preference = DEF_PREF_BGP;
BGP_CFG->hold_time = 240;
BGP_CFG->connect_retry_time = 120;
BGP_CFG->initial_hold_time = 240;
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/proto/ospf/config.Y
^
|
@@ -120,8 +120,10 @@
CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN, VIRTUAL, CHECK, LINK)
CF_KEYWORDS(RX, BUFFER, LARGE, NORMAL, STUBNET, HIDDEN, SUMMARY, TAG, EXTERNAL)
CF_KEYWORDS(WAIT, DELAY, LSADB, ECMP, LIMIT, WEIGHT, NSSA, TRANSLATOR, STABILITY)
+CF_KEYWORDS(GLOBAL, LSID, ROUTER, SELF)
%type <t> opttext
+%type <ld> lsadb_args
CF_GRAMMAR
@@ -129,7 +131,6 @@
ospf_proto_start: proto_start OSPF {
this_proto = proto_config_new(&proto_ospf, sizeof(struct ospf_config), $1);
- this_proto->preference = DEF_PREF_OSPF;
init_list(&OSPF_CFG->area_list);
init_list(&OSPF_CFG->vlink_list);
OSPF_CFG->rfc1583 = DEFAULT_RFC1583;
@@ -218,7 +219,7 @@
ospf_vlink:
ospf_vlink_start '{' ospf_vlink_opts '}' { ospf_iface_finish(); }
- | ospf_vlink_start
+ | ospf_vlink_start { ospf_iface_finish(); }
;
ospf_vlink_opts:
@@ -387,7 +388,8 @@
CF_ADDTO(dynamic_attr, OSPF_TAG { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_OSPF_TAG); })
CF_ADDTO(dynamic_attr, OSPF_ROUTER_ID { $$ = f_new_dynamic_attr(EAF_TYPE_ROUTER_ID | EAF_TEMP, T_QUAD, EA_OSPF_ROUTER_ID); })
-CF_CLI(SHOW OSPF, optsym, [<name>], [[Show information about OSPF protocol]])
+CF_CLI_HELP(SHOW OSPF, ..., [[Show information about OSPF protocol]]);
+CF_CLI(SHOW OSPF, optsym, [<name>], [[Show information about OSPF protocol XXX]])
{ ospf_sh(proto_get_named($3, &proto_ospf)); };
CF_CLI(SHOW OSPF NEIGHBORS, optsym opttext, [<name>] [\"<interface>\"], [[Show information about OSPF neighbors]])
@@ -412,8 +414,23 @@
CF_CLI(SHOW OSPF STATE ALL, optsym opttext, [<name>], [[Show information about all OSPF network state]])
{ ospf_sh_state(proto_get_named($5, &proto_ospf), 1, 0); };
-CF_CLI(SHOW OSPF LSADB, optsym opttext, [<name>], [[Show content of OSPF LSA database]])
-{ ospf_sh_lsadb(proto_get_named($4, &proto_ospf)); };
+CF_CLI_HELP(SHOW OSPF LSADB, ..., [[Show content of OSPF LSA database]]);
+CF_CLI(SHOW OSPF LSADB, lsadb_args, [global | area <id> | link] [type <num>] [lsid <id>] [self | router <id>] [<proto>], [[Show content of OSPF LSA database]])
+{ ospf_sh_lsadb($4); };
+
+lsadb_args:
+ /* empty */ {
+ $$ = cfg_allocz(sizeof(struct lsadb_show_data));
+ }
+ | lsadb_args GLOBAL { $$ = $1; $$->scope = LSA_SCOPE_AS; }
+ | lsadb_args AREA idval { $$ = $1; $$->scope = LSA_SCOPE_AREA; $$->area = $3 }
+ | lsadb_args LINK { $$ = $1; $$->scope = 1; /* hack, 0 is no filter */ }
+ | lsadb_args TYPE NUM { $$ = $1; $$->type = $3; }
+ | lsadb_args LSID idval { $$ = $1; $$->lsid = $3; }
+ | lsadb_args SELF { $$ = $1; $$->router = SH_ROUTER_SELF; }
+ | lsadb_args ROUTER idval { $$ = $1; $$->router = $3; }
+ | lsadb_args SYM { $$ = $1; $$->name = $2; }
+ ;
CF_CODE
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/proto/ospf/dbdes.c
^
|
@@ -96,7 +96,7 @@
pkt = ospf_tx_buffer(ifa);
op = &pkt->ospf_packet;
ospf_pkt_fill_hdr(ifa, pkt, DBDES_P);
- pkt->iface_mtu = htons(ifa->iface->mtu);
+ pkt->iface_mtu = (ifa->type == OSPF_IT_VLINK) ? 0 : htons(ifa->iface->mtu);
pkt->options = hton_opt(oa->options);
pkt->imms = n->myimms;
pkt->ddseq = htonl(n->dds);
@@ -119,7 +119,7 @@
op = (struct ospf_packet *) pkt;
ospf_pkt_fill_hdr(ifa, pkt, DBDES_P);
- pkt->iface_mtu = htons(ifa->iface->mtu);
+ pkt->iface_mtu = (ifa->type == OSPF_IT_VLINK) ? 0 : htons(ifa->iface->mtu);
pkt->ddseq = htonl(n->dds);
pkt->options = hton_opt(oa->options);
@@ -260,6 +260,7 @@
struct ospf_dbdes_packet *ps = (void *) ps_i;
u32 ps_ddseq = ntohl(ps->ddseq);
u32 ps_options = ntoh_opt(ps->options);
+ u16 ps_iface_mtu = ntohs(ps->iface_mtu);
OSPF_PACKET(ospf_dump_dbdes, ps, "DBDES packet received from %I via %s", n->ip, ifa->iface->name);
@@ -277,6 +278,12 @@
if (n->state != NEIGHBOR_EXSTART)
return;
case NEIGHBOR_EXSTART:
+
+ if ((ps_iface_mtu != ifa->iface->mtu) && (ifa->type != OSPF_IT_VLINK)
+ && (ps_iface_mtu != 0) && (ifa->iface->mtu != 0))
+ log(L_WARN "OSPF: MTU mismatch with neighbour %I on interface %s (remote %d, local %d)",
+ n->ip, ifa->iface->name, ps_iface_mtu, ifa->iface->mtu);
+
if ((ps->imms.bit.m && ps->imms.bit.ms && ps->imms.bit.i)
&& (n->rid > po->router_id) && (size == sizeof(struct ospf_dbdes_packet)))
{
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/proto/ospf/iface.c
^
|
@@ -120,6 +120,8 @@
sk->saddr = ifa->addr->ip;
if ((ifa->type == OSPF_IT_BCAST) || (ifa->type == OSPF_IT_PTP))
{
+ sk->ttl = 1; /* Hack, this will affect just multicast packets */
+
if (sk_setup_multicast(sk) < 0)
goto err;
@@ -568,6 +570,9 @@
{
ifa->voa = ospf_find_area(oa->po, ip->voa);
ifa->vid = ip->vid;
+
+ ifa->hello_timer = tm_new_set(ifa->pool, hello_timer_hook, ifa, 0, ifa->helloint);
+
return; /* Don't lock, don't add sockets */
}
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/proto/ospf/lsalib.c
^
|
@@ -512,7 +512,6 @@
* @lsa: LSA header
* @domain: domain of LSA
* @body: pointer to LSA body
-
*
* This function ensures installing new LSA into LSA database. Old instance is
* replaced. Several actions are taken to detect if new routing table
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/proto/ospf/ospf.c
^
|
@@ -1471,8 +1471,9 @@
}
void
-ospf_sh_lsadb(struct proto *p)
+ospf_sh_lsadb(struct lsadb_show_data *ld)
{
+ struct proto *p = proto_get_named(ld->name, &proto_ospf);
struct proto_ospf *po = (struct proto_ospf *) p;
int num = po->gr->hash_entries;
unsigned int i, j;
@@ -1486,6 +1487,9 @@
return;
}
+ if (ld->router == SH_ROUTER_SELF)
+ ld->router = po->router_id;
+
struct top_hash_entry *hea[num];
struct top_hash_entry *he;
@@ -1502,6 +1506,22 @@
{
struct ospf_lsa_header *lsa = &(hea[i]->lsa);
int dscope = LSA_SCOPE(lsa);
+
+ if (ld->scope && (dscope != (ld->scope & 0xf000)))
+ continue;
+
+ if ((ld->scope == LSA_SCOPE_AREA) && (hea[i]->domain != ld->area))
+ continue;
+
+ /* Ignore high nibble */
+ if (ld->type && ((lsa->type & 0x0fff) != (ld->type & 0x0fff)))
+ continue;
+
+ if (ld->lsid && (lsa->id != ld->lsid))
+ continue;
+
+ if (ld->router && (lsa->rt != ld->router))
+ continue;
if ((dscope != last_dscope) || (hea[i]->domain != last_domain))
{
@@ -1542,6 +1562,7 @@
name: "OSPF",
template: "ospf%d",
attr_class: EAP_OSPF,
+ preference: DEF_PREF_OSPF,
init: ospf_init,
dump: ospf_dump,
start: ospf_start,
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/proto/ospf/ospf.h
^
|
@@ -177,7 +177,7 @@
struct ospf_iface
{
node n;
- struct iface *iface; /* Nest's iface */
+ struct iface *iface; /* Nest's iface, non-NULL (unless type OSPF_IT_VLINK) */
struct ifa *addr; /* IP prefix associated with that OSPF iface */
struct ospf_area *oa;
struct ospf_iface_patt *cf;
@@ -846,7 +846,19 @@
void ospf_sh(struct proto *p);
void ospf_sh_iface(struct proto *p, char *iff);
void ospf_sh_state(struct proto *p, int verbose, int reachable);
-void ospf_sh_lsadb(struct proto *p);
+
+#define SH_ROUTER_SELF 0xffffffff
+
+struct lsadb_show_data {
+ struct symbol *name; /* Protocol to request data from */
+ u16 type; /* LSA Type, 0 -> all */
+ u16 scope; /* Scope, 0 -> all, hack to handle link scope as 1 */
+ u32 area; /* Specified for area scope */
+ u32 lsid; /* LSA ID, 0 -> all */
+ u32 router; /* Advertising router, 0 -> all */
+};
+
+void ospf_sh_lsadb(struct lsadb_show_data *ld);
#define EA_OSPF_METRIC1 EA_CODE(EAP_OSPF, 0)
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/proto/ospf/packet.c
^
|
@@ -489,17 +489,17 @@
void
ospf_tx_hook(sock * sk)
{
-// struct ospf_iface *ifa= (struct ospf_iface *) (sk->data);
+ struct ospf_iface *ifa= (struct ospf_iface *) (sk->data);
// struct proto *p = (struct proto *) (ifa->oa->po);
- log(L_ERR "OSPF: TX_Hook called");
+ log(L_ERR "OSPF: TX hook called on %s", ifa->iface->name);
}
void
ospf_err_hook(sock * sk, int err)
{
-// struct ospf_iface *ifa= (struct ospf_iface *) (sk->data);
+ struct ospf_iface *ifa= (struct ospf_iface *) (sk->data);
// struct proto *p = (struct proto *) (ifa->oa->po);
- log(L_ERR "OSPF: Socket error: %M", err);
+ log(L_ERR "OSPF: Socket error on %s: %M", ifa->iface->name, err);
}
void
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/proto/pipe/config.Y
^
|
@@ -24,7 +24,6 @@
pipe_proto_start: proto_start PIPE {
this_proto = proto_config_new(&proto_pipe, sizeof(struct pipe_config), $1);
- this_proto->preference = DEF_PREF_PIPE;
PIPE_CFG->mode = PIPE_TRANSPARENT;
}
;
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/proto/pipe/pipe.c
^
|
@@ -197,6 +197,7 @@
struct protocol proto_pipe = {
name: "Pipe",
template: "pipe%d",
+ preference: DEF_PREF_PIPE,
postconfig: pipe_postconfig,
init: pipe_init,
start: pipe_start,
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/proto/rip/rip.c
^
|
@@ -146,7 +146,11 @@
DBG( "Preparing packet to send: " );
packet->heading.command = RIPCMD_RESPONSE;
+#ifndef IPV6
packet->heading.version = RIP_V2;
+#else
+ packet->heading.version = RIP_NG;
+#endif
packet->heading.unused = 0;
i = !!P_CF->authtype;
@@ -281,7 +285,7 @@
* bird core with this route.
*/
static void
-advertise_entry( struct proto *p, struct rip_block *b, ip_addr whotoldme )
+advertise_entry( struct proto *p, struct rip_block *b, ip_addr whotoldme, struct iface *iface )
{
rta *a, A;
rte *r;
@@ -309,7 +313,7 @@
/* No need to look if destination looks valid - ie not net 0 or 127 -- core will do for us. */
- neighbor = neigh_find( p, &A.gw, 0 );
+ neighbor = neigh_find2( p, &A.gw, iface, 0 );
if (!neighbor) {
log( L_REMOTE "%s: %I asked me to route %I/%d using not-neighbor %I.", p->name, A.from, b->network, pxlen, A.gw );
return;
@@ -353,7 +357,7 @@
* process_block - do some basic check and pass block to advertise_entry
*/
static void
-process_block( struct proto *p, struct rip_block *block, ip_addr whotoldme )
+process_block( struct proto *p, struct rip_block *block, ip_addr whotoldme, struct iface *iface )
{
#ifndef IPV6
int metric = ntohl( block->metric );
@@ -380,7 +384,7 @@
return;
}
- advertise_entry( p, block, whotoldme );
+ advertise_entry( p, block, whotoldme, iface );
}
#define BAD( x ) { log( L_REMOTE "%s: " x, p->name ); return 1; }
@@ -389,7 +393,7 @@
* rip_process_packet - this is main routine for incoming packets.
*/
static int
-rip_process_packet( struct proto *p, struct rip_packet *packet, int num, ip_addr whotoldme, int port )
+rip_process_packet( struct proto *p, struct rip_packet *packet, int num, ip_addr whotoldme, int port, struct iface *iface )
{
int i;
int authenticated = 0;
@@ -406,7 +410,7 @@
if (P_CF->honor == HO_NEVER)
BAD( "They asked me to send routing table, but I was told not to do it" );
- if ((P_CF->honor == HO_NEIGHBOR) && (!neigh_find( p, &whotoldme, 0 )))
+ if ((P_CF->honor == HO_NEIGHBOR) && (!neigh_find2( p, &whotoldme, iface, 0 )))
BAD( "They asked me to send routing table, but he is not my neighbor" );
rip_sendto( p, whotoldme, port, HEAD(P->interfaces) ); /* no broadcast */
break;
@@ -416,7 +420,7 @@
return 1;
}
- if (!(neighbor = neigh_find( p, &whotoldme, 0 )) || neighbor->scope == SCOPE_HOST) {
+ if (!(neighbor = neigh_find2( p, &whotoldme, iface, 0 )) || neighbor->scope == SCOPE_HOST) {
log( L_REMOTE "%s: %I send me routing info but he is not my neighbor", p->name, whotoldme );
return 0;
}
@@ -443,7 +447,7 @@
if (packet->heading.version == RIP_V1) /* FIXME (nonurgent): switch to disable this? */
block->netmask = ipa_class_mask(block->network);
#endif
- process_block( p, block, whotoldme );
+ process_block( p, block, whotoldme, iface );
}
break;
case RIPCMD_TRACEON:
@@ -463,12 +467,20 @@
{
struct rip_interface *i = s->data;
struct proto *p = i->proto;
+ struct iface *iface = NULL;
int num;
/* In non-listening mode, just ignore packet */
if (i->mode & IM_NOLISTEN)
return 1;
+#ifdef IPV6
+ if (! i->iface || s->lifindex != i->iface->index)
+ return 1;
+
+ iface = i->iface;
+#endif
+
CHK_MAGIC;
DBG( "RIP: message came: %d bytes from %I via %s\n", size, s->faddr, i->iface ? i->iface->name : "(dummy)" );
size -= sizeof( struct rip_packet_heading );
@@ -477,17 +489,12 @@
num = size / sizeof( struct rip_block );
if (num>PACKET_MAX) BAD( "Too many blocks" );
-#ifdef IPV6
- /* Try to absolutize link scope addresses */
- ipa_absolutize(&s->faddr, &i->iface->addr->ip);
-#endif
-
if (ipa_equal(i->iface->addr->ip, s->faddr)) {
DBG("My own packet\n");
return 1;
}
- rip_process_packet( p, (struct rip_packet *) s->rbuf, num, s->faddr, s->fport );
+ rip_process_packet( p, (struct rip_packet *) s->rbuf, num, s->faddr, s->fport, iface );
return 1;
}
@@ -701,6 +708,7 @@
{
rif->sock->ttl = 1;
rif->sock->tos = IP_PREC_INTERNET_CONTROL;
+ rif->sock->flags = SKF_LADDR_RX;
}
if (new) {
@@ -712,7 +720,6 @@
rif->sock->daddr = ipa_from_u32(0xe0000009);
#else
rif->sock->daddr = ipa_build(0xff020000, 0, 0, 9);
- rif->sock->saddr = new->addr->ip; /* Does not really work on Linux */
#endif
} else {
rif->sock->daddr = new->addr->brd;
@@ -975,9 +982,8 @@
rip_init_config(struct rip_proto_config *c)
{
init_list(&c->iface_list);
- c->c.preference = DEF_PREF_RIP;
c->infinity = 16;
- c->port = 520;
+ c->port = RIP_PORT;
c->period = 30;
c->garbage_time = 120+180;
c->timeout_time = 120;
@@ -1032,6 +1038,7 @@
name: "RIP",
template: "rip%d",
attr_class: EAP_RIP,
+ preference: DEF_PREF_RIP,
get_route_info: rip_get_route_info,
get_attr: rip_get_attr,
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/proto/rip/rip.h
^
|
@@ -11,8 +11,19 @@
#define EA_RIP_TAG EA_CODE(EAP_RIP, 0)
#define EA_RIP_METRIC EA_CODE(EAP_RIP, 1)
-#define PACKET_MAX 25
-#define PACKET_MD5_MAX 18 /* FIXME */
+#define PACKET_MAX 25
+#define PACKET_MD5_MAX 18 /* FIXME */
+
+
+#define RIP_V1 1
+#define RIP_V2 2
+#define RIP_NG 1 /* A new version numbering */
+
+#ifndef IPV6
+#define RIP_PORT 520 /* RIP for IPv4 */
+#else
+#define RIP_PORT 521 /* RIPng */
+#endif
struct rip_connection {
node n;
@@ -37,8 +48,9 @@
#define RIPCMD_TRACEOFF 4 /* turn it off */
#define RIPCMD_MAX 5
u8 version;
-#define RIP_V1 1
-#define RIP_V2 2
+#define RIP_V1 1
+#define RIP_V2 2
+#define RIP_NG 1 /* this is verion 1 of RIPng */
u16 unused;
};
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/proto/static/static.c
^
|
@@ -353,7 +353,6 @@
void
static_init_config(struct static_config *c)
{
- c->c.preference = DEF_PREF_STATIC;
init_list(&c->iface_routes);
init_list(&c->other_routes);
}
@@ -523,6 +522,7 @@
struct protocol proto_static = {
name: "Static",
template: "static%d",
+ preference: DEF_PREF_STATIC,
init: static_init,
dump: static_dump,
start: static_start,
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/sysdep/bsd/krt-sock.c
^
|
@@ -410,14 +410,42 @@
}
static void
+krt_read_ifannounce(struct ks_msg *msg)
+{
+ struct if_announcemsghdr *ifam = (struct if_announcemsghdr *)&msg->rtm;
+
+ if (ifam->ifan_what == IFAN_ARRIVAL)
+ {
+ /* Not enough info to create the iface, so we just trigger iface scan */
+ kif_request_scan();
+ }
+ else if (ifam->ifan_what == IFAN_DEPARTURE)
+ {
+ struct iface *iface = if_find_by_index(ifam->ifan_index);
+
+ /* Interface is destroyed */
+ if (!iface)
+ {
+ DBG("KRT: unknown interface (%s, #%d) going down. Ignoring\n", ifam->ifan_name, ifam->ifan_index);
+ return;
+ }
+
+ if_delete(iface);
+ }
+
+ DBG("KRT: IFANNOUNCE what: %d index %d name %s\n", ifam->ifan_what, ifam->ifan_index, ifam->ifan_name);
+}
+
+static void
krt_read_ifinfo(struct ks_msg *msg)
{
struct if_msghdr *ifm = (struct if_msghdr *)&msg->rtm;
void *body = (void *)(ifm + 1);
struct sockaddr_dl *dl = NULL;
unsigned int i;
- struct iface *iface = NULL, f;
+ struct iface *iface = NULL, f = {};
int fl = ifm->ifm_flags;
+ int nlen = 0;
for (i = 1; i<=RTA_IFP; i <<= 1)
{
@@ -432,31 +460,42 @@
}
}
- if(dl && (dl->sdl_family != AF_LINK))
+ if (dl && (dl->sdl_family != AF_LINK))
{
- log("Ignoring strange IFINFO");
+ log(L_WARN "Ignoring strange IFINFO");
return;
}
- iface = if_find_by_index(ifm->ifm_index);
+ if (dl)
+ nlen = MIN(sizeof(f.name)-1, dl->sdl_nlen);
- if(!iface)
+ /* Note that asynchronous IFINFO messages do not contain iface
+ name, so we have to found an existing iface by iface index */
+
+ iface = if_find_by_index(ifm->ifm_index);
+ if (!iface)
{
/* New interface */
- if(!dl) return; /* No interface name, ignoring */
+ if (!dl)
+ return; /* No interface name, ignoring */
- bzero(&f, sizeof(f));
- f.index = ifm->ifm_index;
- memcpy(f.name, dl->sdl_data, MIN(sizeof(f.name)-1, dl->sdl_nlen));
- DBG("New interface '%s' found", f.name);
+ memcpy(f.name, dl->sdl_data, nlen);
+ DBG("New interface '%s' found\n", f.name);
+ }
+ else if (dl && memcmp(iface->name, dl->sdl_data, nlen))
+ {
+ /* Interface renamed */
+ if_delete(iface);
+ memcpy(f.name, dl->sdl_data, nlen);
}
else
{
- memcpy(&f, iface, sizeof(struct iface));
+ /* Old interface */
+ memcpy(f.name, iface->name, sizeof(f.name));
}
+ f.index = ifm->ifm_index;
f.mtu = ifm->ifm_data.ifi_mtu;
- f.flags = 0;
if (fl & IFF_UP)
f.flags |= IF_ADMIN_UP;
@@ -471,8 +510,7 @@
else
f.flags |= IF_MULTIACCESS; /* NBMA */
- if((!iface) || memcmp(&f, iface, sizeof(struct iface)))
- if_update(&f); /* Just if something happens */
+ if_update(&f);
}
static void
@@ -588,6 +626,9 @@
case RTM_DELETE:
krt_read_rt(msg, (struct krt_proto *)p, scan);
break;
+ case RTM_IFANNOUNCE:
+ krt_read_ifannounce(msg);
+ break;
case RTM_IFINFO:
krt_read_ifinfo(msg);
break;
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/sysdep/config.h
^
|
@@ -7,7 +7,7 @@
#define _BIRD_CONFIG_H_
/* BIRD version */
-#define BIRD_VERSION "1.3.6"
+#define BIRD_VERSION "1.3.7"
/* Include parameters determined by configure script */
#include "sysdep/autoconf.h"
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/sysdep/linux/netlink/netlink.c
^
|
@@ -386,7 +386,7 @@
struct ifinfomsg *i;
struct rtattr *a[IFLA_WIRELESS+1];
int new = h->nlmsg_type == RTM_NEWLINK;
- struct iface f;
+ struct iface f = {};
struct iface *ifi;
char *name;
u32 mtu;
@@ -408,26 +408,21 @@
if (!new)
{
DBG("KIF: IF%d(%s) goes down\n", i->ifi_index, name);
- if (ifi && !scan)
- {
- memcpy(&f, ifi, sizeof(struct iface));
- f.flags |= IF_SHUTDOWN;
- if_update(&f);
- }
+ if (!ifi)
+ return;
+
+ if_delete(ifi);
}
else
{
DBG("KIF: IF%d(%s) goes up (mtu=%d,flg=%x)\n", i->ifi_index, name, mtu, i->ifi_flags);
- if (ifi)
- memcpy(&f, ifi, sizeof(f));
- else
- {
- bzero(&f, sizeof(f));
- f.index = i->ifi_index;
- }
- strncpy(f.name, RTA_DATA(a[IFLA_IFNAME]), sizeof(f.name)-1);
+ if (ifi && strncmp(ifi->name, name, sizeof(ifi->name)-1))
+ if_delete(ifi);
+
+ strncpy(f.name, name, sizeof(f.name)-1);
+ f.index = i->ifi_index;
f.mtu = mtu;
- f.flags = 0;
+
fl = i->ifi_flags;
if (fl & IFF_UP)
f.flags |= IF_ADMIN_UP;
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/sysdep/unix/krt.Y
^
|
@@ -31,7 +31,6 @@
cf_error("Kernel protocol already defined");
#endif
cf_krt = this_proto = proto_config_new(&proto_unix_kernel, sizeof(struct krt_config), $1);
- this_proto->preference = DEF_PREF_INHERITED;
THIS_KRT->scan_time = 60;
THIS_KRT->learn = THIS_KRT->persist = 0;
krt_scan_construct(THIS_KRT);
@@ -67,7 +66,6 @@
if (cf_kif)
cf_error("Kernel device protocol already defined");
cf_kif = this_proto = proto_config_new(&proto_unix_iface, sizeof(struct kif_config), $1);
- this_proto->preference = DEF_PREF_DIRECT;
THIS_KIF->scan_time = 60;
init_list(&THIS_KIF->primary);
krt_if_construct(THIS_KIF);
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/sysdep/unix/krt.c
^
|
@@ -104,6 +104,13 @@
}
}
+void
+kif_request_scan(void)
+{
+ if (kif_proto && kif_scan_timer->expires > now)
+ tm_start(kif_scan_timer, 1);
+}
+
static struct proto *
kif_init(struct proto_config *c)
{
@@ -236,6 +243,7 @@
struct protocol proto_unix_iface = {
name: "Device",
template: "device%d",
+ preference: DEF_PREF_DIRECT,
preconfig: kif_preconfig,
init: kif_init,
start: kif_start,
@@ -600,10 +608,9 @@
return;
}
- if (net->n.flags & KRF_INSTALLED)
+ old = net->routes;
+ if ((net->n.flags & KRF_INSTALLED) && old)
{
- old = net->routes;
- ASSERT(old);
if (krt_uptodate(e, old))
verdict = KRF_SEEN;
else
@@ -961,6 +968,7 @@
name: "Kernel",
template: "kernel%d",
attr_class: EAP_KRT,
+ preference: DEF_PREF_INHERITED,
preconfig: krt_preconfig,
postconfig: krt_postconfig,
init: krt_init,
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/sysdep/unix/krt.h
^
|
@@ -77,6 +77,7 @@
if (pr->p.debug & fl) \
{ log(L_TRACE "%s: " msg, pr->p.name , ## args); } } while(0)
+void kif_request_scan(void);
void krt_got_route(struct krt_proto *p, struct rte *e);
void krt_got_route_async(struct krt_proto *p, struct rte *e, int new);
|
[-]
[+]
|
Changed |
bird-1.3.7.tar.bz2/sysdep/unix/main.c
^
|
@@ -170,7 +170,10 @@
int ret;
if (*filename != '/') {
- snprintf(full_name, sizeof(full_name), "%s/%s", dirname(config_name), filename);
+ char dir[BIRD_FNAME_MAX];
+ strncpy(dir, config_name, sizeof(dir));
+ dir[sizeof(dir)-1] = 0;
+ snprintf(full_name, sizeof(full_name), "%s/%s", dirname(dir), filename);
full_name[sizeof(full_name)-1] = 0;
cur = full_name;
}
@@ -643,6 +646,7 @@
io_init();
rt_init();
if_init();
+ roa_init();
uid_t use_uid = get_uid(use_user);
gid_t use_gid = get_gid(use_group);
|