Commit 65d2a88d authored by Pavel Tvrdík's avatar Pavel Tvrdík Committed by Jan Moskyto Matejka

RPKI protocol with one cache server per protocol

The RPKI protocol (RFC 6810) using the RTRLib
(http://rpki.realmv6.org/) that is integrated inside
the BIRD's code.

Implemeted transports are:
 - unprotected transport over TCP
 - secure transport over SSHv2

Example configuration of bird.conf:
  ...
  roa4 table r4;
  roa6 table r6;

  protocol rpki {
    debug all;

    # Import both IPv4 and IPv6 ROAs
    roa4 { table r4; };
    roa6 { table r6; };

    # Set cache server (validator) address,
    # overwrite default port 323
    remote "rpki-validator.realmv6.org" port 8282;

    # Overwrite default time intervals
    retry   10;         # Default 600 seconds
    refresh 60;         # Default 3600 seconds
    expire 600;         # Default 7200 seconds
  }

  protocol rpki {
    debug all;

    # Import only IPv4 routes
    roa4 { table r4; };

    # Set cache server address to localhost,
    # use default ports tcp => 323 or ssh => 22
    remote 127.0.0.1;

    # Use SSH transport instead of unprotected transport over TCP
    ssh encryption {
      bird private key "/home/birdgeek/.ssh/id_rsa";
      remote public key "/home/birdgeek/.ssh/known_hosts";
      user "birdgeek";
    };
  }
  ...
parent 2706747f
......@@ -10,6 +10,7 @@ CPPFLAGS=-I$(objdir) -I$(srcdir) @CPPFLAGS@
CFLAGS=$(CPPFLAGS) @CFLAGS@
LDFLAGS=@LDFLAGS@
LIBS=@LIBS@
DAEMON_LIBS=@DAEMON_LIBS@
CLIENT_LIBS=@CLIENT_LIBS@
CC=@CC@
M4=@M4@
......@@ -57,6 +58,8 @@ all: daemon cli
daemon: $(daemon)
cli: $(client)
$(daemon): LIBS += $(DAEMON_LIBS)
# Include directories
dirs := client conf doc filter lib nest $(addprefix proto/,$(protocols)) @sysdep_dirs@
......
......@@ -168,7 +168,7 @@ fi
AC_SUBST(iproutedir)
# all_protocols="$proto_bfd babel bgp ospf pipe radv rip static"
all_protocols="$proto_bfd ospf pipe radv rip static"
all_protocols="$proto_bfd babel ospf pipe radv rip rpki static "
all_protocols=`echo $all_protocols | sed 's/ /,/g'`
......@@ -226,6 +226,10 @@ if test "$enable_debug" = yes ; then
fi
fi
DAEMON_LIBS=
AC_CHECK_LIB(dl, dlopen, DAEMON_LIBS="-ldl")
AC_SUBST(DAEMON_LIBS)
CLIENT=birdcl
CLIENT_LIBS=
if test "$enable_client" = yes ; then
......
......@@ -469,7 +469,7 @@ protocol rip {
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
an AS (Autonomous System) 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.
......@@ -3595,7 +3595,7 @@ protocol rip [&lt;name&gt;] {
<descrip>
<tag>int <cf/rip_metric/</tag>
RIP metric of the route (ranging from 0 to <cf/infinity/). When routes
RIP metric of the route (ranging from 0 to <cf/infinity/). When routes
from different RIP instances are available and all of them have the same
preference, BIRD prefers the route with lowest <cf/rip_metric/. When a
non-RIP route is exported to RIP, the default metric is 1.
......@@ -3623,6 +3623,184 @@ protocol rip {
}
</code>
<sect>RPKI
<sect1>Introduction
<p>The Resource Public Key Infrastructure (RPKI) is mechanism for origin
validation of BGP routes (RFC 6480). BIRD supports only so-called RPKI-based
origin validation. There is implemented RPKI to Router (RPKI-RTR) protocol (RFC
6810). It uses some of the RPKI data to allow a router to verify that the
autonomous system announcing an IP address prefix is in fact authorized to do
so. This is not crypto checked so can be violated. But it should prevent the
vast majority of accidental hijackings on the Internet today, e.g. the famous
Pakastani accidental announcement of YouTube's address space.
<p>The RPKI-RTR protocol receives and maintains a set of ROAs from a cache
server (also called validator). You can validate routes (RFC 6483) using
function <cf/roa_check()/ in filter and set it as import filter at the BGP
protocol. BIRD should re-validate all of affected routes after RPKI update by
RFC 6811, but we don't support it yet! You can use a BIRD's client command
<cf>reload in <m/bgp_protocol_name/</cf> for manual call of revalidation of all
routes.
<sect1>Supported transports
<itemize>
<item>Unprotected transport over TCP uses a port 323. The cache server
and BIRD router should be on the same trusted and controlled network
for security reasons.
<item>SSHv2 encrypted transport connection uses the normal SSH port
22.
</itemize>
<sect1>Configuration
<p>We currently support just one cache server per protocol. However you can
define more RPKI protocols generally.
<code>
protocol rpki [&lt;name&gt;] {
roa4 { table &lt;tab&gt;; };
roa6 { table &lt;tab&gt;; };
remote &lt;ip&gt; | "&lt;domain&gt;" [port &lt;num&gt;];
port &lt;num&gt;;
refresh [keep] &lt;num&gt;;
retry [keep] &lt;num&gt;;
expire [keep] &lt;num&gt;;
transport tcp;
transport ssh {
bird private key "&lt;/path/to/id_rsa&gt;";
remote public key "&lt;/path/to/known_host&gt;";
user "&lt;name&gt;";
};
}
</code>
<p>Alse note that you have to specify ROA table into which will be imported
routes from a cache server. If you want to import only IPv4 prefixes you have
to specify only roa4 table. Similarly with IPv6 prefixes only. If you want to
fetch both IPv4 and even IPv6 ROAs you have to specify both types of ROA
tables.
<sect2>RPKI protocol options
<descrip>
<tag>remote <m/ip/ | "<m/hostname/" [port <m/num/]</tag> Specifies
a destination address of the cache server. Can be specified by an IP
address or by full domain name string. Only one cache can be specified
per protocol. This option is required.
<tag>port <m/num/</tag> Specifies the port number. The default port
number is 323 for transport without any encryption and 22 for transport
with SSH encryption.
<tag>refresh [keep] <m/num/</tag> Time period in seconds. Tells how
long to wait before next attempting to poll the cache using a Serial
Query or a Reset Query packet. Must be lower than 86400 seconds (one
day). Too low value can caused a false positive detection of
network connection problems. A keyword <cf/keep/ suppresses updating
this value by a cache server.
Default: 3600 seconds
<tag>retry [keep] <m/num/</tag> Time period in seconds between a failed
Serial/Reset Query and a next attempt. Maximum allowed value is 7200
seconds (two hours). Too low value can caused a false positive
detection of network connection problems. A keyword <cf/keep/
suppresses updating this value by a cache server.
Default: 600 seconds
<tag>expire [keep] <m/num/</tag> Time period in seconds. Received
records are deleted if the client was unable to successfully refresh
data for this time period. Must be in range from 600 seconds (ten
minutes) to 172800 seconds (two days). A keyword <cf/keep/
suppresses updating this value by a cache server.
Default: 7200 seconds
<tag>transport tcp</tag> Unprotected transport over TCP. It's a default
transport. Should be used only on secure private networks.
Default: tcp
<tag>transport ssh { <m/SSH transport options.../ }</tag> It enables a
SSHv2 transport encryption. Cannot be combined with a TCP transport.
Default: off
</descrip>
<sect3>SSH transport options
<descrip>
<tag>bird private key "<m>/path/to/id_rsa</m>"</tag>
A path to the BIRD's private SSH key for authentication.
It can be a <cf><m>id_rsa</m></cf> file.
<tag>remote public key "<m>/path/to/known_host</m>"</tag>
A path to the cache's public SSH key for verification identity
of the cache server. It could be a path to <cf><m>known_host</m></cf> file.
<tag>user "<m/name/"</tag>
A SSH user name for authentication. This option is a required.
</descrip>
<sect1>Examples
<sect2>BGP origin validation
<p>Policy: Don't import <cf/ROA_INVALID/ routes.
<code>
roa4 table r4;
roa6 table r6;
protocol rpki {
debug all;
roa4 { table r4; };
roa6 { table r6; };
# Please, do not use rpki-validator.realmv6.org in production
remote "rpki-validator.realmv6.org" port 8282;
retry keep 5;
refresh keep 30;
expire 600;
}
filter peer_in {
if (roa_check(r4, net, bgp_path.last) = ROA_INVALID ||
roa_check(r6, net, bgp_path.last) = ROA_INVALID) then
{
print "Ignore invalid ROA ", net, " for ASN ", bgp_path.last;
reject;
}
accept;
}
protocol bgp {
debug all;
local as 65000;
neighbor 192.168.2.1 as 65001;
import filter peer_in;
}
</code>
<sect2>SSHv2 transport encryption
<code>
roa4 table r4;
roa6 table r6;
protocol rpki {
debug all;
roa4 { table r4; };
roa6 { table r6; };
remote 127.0.0.1 port 2345;
transport ssh {
bird private key "/home/birdgeek/.ssh/id_rsa";
remote public key "/home/birdgeek/.ssh/known_hosts";
user "birdgeek";
};
# Default interval values
}
</code>
<sect>Static
......
......@@ -1280,12 +1280,15 @@ interpret(struct f_inst *what)
if (!table)
runtime("Missing ROA table");
/* Table type is either NET_ROA4 or NET_ROA6, checked in parser */
if (v1.val.net->type != ((table->addr_type == NET_ROA4) ? NET_IP4 : NET_IP6))
runtime("Incompatible net type");
if (table->addr_type != NET_ROA4 && table->addr_type != NET_ROA6)
runtime("Table type must be either ROA4 or ROA6");
res.type = T_ENUM_ROA;
res.val.i = net_roa_check(table, v1.val.net, as);
if (table->addr_type != (v1.val.net->type == NET_IP4 ? NET_ROA4 : NET_ROA6))
res.val.i = ROA_UNKNOWN; /* Prefix and table type mismatch */
else
res.val.i = net_roa_check(table, v1.val.net, as);
break;
......
src := bitops.c checksum.c event.c idm.c ip.c lists.c md5.c mempool.c net.c patmatch.c printf.c resource.c sha1.c sha256.c sha512.c slab.c slists.c tbf.c xmalloc.c
src := bitops.c checksum.c ip.c lists.c md5.c net.c patmatch.c printf.c sha1.c sha256.c sha512.c slists.c xmalloc.c
obj := $(src-o-files)
$(all-client)
src := bitops.c checksum.c event.c idm.c ip.c libssh.c lists.c md5.c mempool.c net.c patmatch.c printf.c resource.c sha1.c sha256.c sha512.c slab.c slists.c tbf.c xmalloc.c
obj := $(src-o-files)
$(all-daemon)
/*
* BIRD -- Mockup of SSH Library for loading LibSSH using dlopen
*
* (c) 2015 CZ.NIC
*
* This file was part of SSH Library: http://www.libssh.org/
* (c) 2003-2009 by Aris Adamantiadis (SSH Library)
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
#include <dlfcn.h>
#include "nest/bird.h"
#include "lib/libssh.h"
#define FILENAME_OF_SHARED_OBJECT_LIBSSH "libssh.so"
struct ssh_function {
void **fn;
const char *name;
};
ssh_session (*ssh_new)(void);
void (*ssh_set_blocking)(ssh_session session, int blocking);
int (*ssh_options_set)(ssh_session session, enum ssh_options_e type, const void *value);
int (*ssh_connect)(ssh_session session);
socket_t (*ssh_get_fd)(ssh_session session);
int (*ssh_is_server_known)(ssh_session session);
int (*ssh_userauth_publickey_auto)(ssh_session session, const char *username, const char *passphrase);
const char * (*ssh_get_error)(void *error);
int (*ssh_get_error_code)(void *error);
void (*ssh_disconnect)(ssh_session session);
void (*ssh_free)(ssh_session session);
ssh_channel (*ssh_channel_new)(ssh_session session);
int (*ssh_channel_is_open)(ssh_channel channel);
int (*ssh_channel_close)(ssh_channel channel);
void (*ssh_channel_free)(ssh_channel channel);
int (*ssh_channel_open_session)(ssh_channel channel);
int (*ssh_channel_request_subsystem)(ssh_channel channel, const char *subsystem);
int (*ssh_channel_read_nonblocking)(ssh_channel channel, void *dest, uint32_t count, int is_stderr);
int (*ssh_channel_is_eof)(ssh_channel channel);
int (*ssh_channel_select)(ssh_channel *readchans, ssh_channel *writechans, ssh_channel *exceptchans, struct timeval * timeout);
int (*ssh_channel_write)(ssh_channel channel, const void *data, uint32_t len);
#define SSH_FN(x) { .fn = (void **) &x, .name = #x }
static struct ssh_function all_ssh_fn[] = {
SSH_FN(ssh_new),
SSH_FN(ssh_set_blocking),
SSH_FN(ssh_options_set),
SSH_FN(ssh_connect),
SSH_FN(ssh_get_fd),
SSH_FN(ssh_is_server_known),
SSH_FN(ssh_userauth_publickey_auto),
SSH_FN(ssh_get_error),
SSH_FN(ssh_get_error_code),
SSH_FN(ssh_disconnect),
SSH_FN(ssh_free),
SSH_FN(ssh_channel_new),
SSH_FN(ssh_channel_is_open),
SSH_FN(ssh_channel_close),
SSH_FN(ssh_channel_free),
SSH_FN(ssh_channel_open_session),
SSH_FN(ssh_channel_request_subsystem),
SSH_FN(ssh_channel_read_nonblocking),
SSH_FN(ssh_channel_is_eof),
SSH_FN(ssh_channel_select),
SSH_FN(ssh_channel_write),
};
#undef SSH_FN
static void *libssh;
/**
* load_libssh - Prepare all ssh_* functions
*
* Initialize for use all ssh_* functions. Returns normally NULL.
* If an error occurs then returns static string with the error description.
*/
const char *
load_libssh(void)
{
char *err_buf;
libssh = dlopen(FILENAME_OF_SHARED_OBJECT_LIBSSH, RTLD_LAZY);
if (!libssh)
{
/* This would be probably often repeated problem */
char *help_msg = "You have to install libssh library.";
err_buf = mb_alloc(&root_pool, 512); /* FIXME: free memory */
bsnprintf(err_buf, 512, "%s. %s", dlerror(), help_msg);
return err_buf;
}
dlerror(); /* Clear any existing error */
for (int i = 0; i < sizeof(all_ssh_fn)/sizeof(all_ssh_fn[0]); i++)
{
*all_ssh_fn[i].fn = (void *) dlsym(libssh, all_ssh_fn[i].name);
err_buf = dlerror();
if (err_buf)
return err_buf;
}
return NULL;
}
/*
* BIRD -- Mockup headers of SSH Library for loading LibSSH using dlopen
*
* (c) 2015 CZ.NIC
*
* This file was part of SSH Library: http://www.libssh.org/
* (c) 2003-2009 by Aris Adamantiadis (SSH Library)
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
#ifndef _BIRD_LIBSSH_H_
#define _BIRD_LIBSSH_H_
#include <unistd.h>
#include <inttypes.h>
typedef struct ssh_session_struct* ssh_session;
typedef struct ssh_channel_struct* ssh_channel;
/* Error return codes */
#define SSH_OK 0 /* No error */
#define SSH_ERROR -1 /* Error of some kind */
#define SSH_AGAIN -2 /* The nonblocking call must be repeated */
#define SSH_EOF -127 /* We have already a eof */
enum ssh_server_known_e {
SSH_SERVER_ERROR=-1,
SSH_SERVER_NOT_KNOWN=0,
SSH_SERVER_KNOWN_OK,
SSH_SERVER_KNOWN_CHANGED,
SSH_SERVER_FOUND_OTHER,
SSH_SERVER_FILE_NOT_FOUND
};
enum ssh_auth_e {
SSH_AUTH_SUCCESS=0,
SSH_AUTH_DENIED,
SSH_AUTH_PARTIAL,
SSH_AUTH_INFO,
SSH_AUTH_AGAIN,
SSH_AUTH_ERROR=-1
};
enum ssh_error_types_e {
SSH_NO_ERROR=0,
SSH_REQUEST_DENIED,
SSH_FATAL,
SSH_EINTR
};
enum ssh_options_e {
SSH_OPTIONS_HOST,
SSH_OPTIONS_PORT,
SSH_OPTIONS_PORT_STR,
SSH_OPTIONS_FD,
SSH_OPTIONS_USER,
SSH_OPTIONS_SSH_DIR,
SSH_OPTIONS_IDENTITY,
SSH_OPTIONS_ADD_IDENTITY,
SSH_OPTIONS_KNOWNHOSTS,
SSH_OPTIONS_TIMEOUT,
SSH_OPTIONS_TIMEOUT_USEC,
SSH_OPTIONS_SSH1,
SSH_OPTIONS_SSH2,
SSH_OPTIONS_LOG_VERBOSITY,
SSH_OPTIONS_LOG_VERBOSITY_STR,
SSH_OPTIONS_CIPHERS_C_S,
SSH_OPTIONS_CIPHERS_S_C,
SSH_OPTIONS_COMPRESSION_C_S,
SSH_OPTIONS_COMPRESSION_S_C,
SSH_OPTIONS_PROXYCOMMAND,
SSH_OPTIONS_BINDADDR,
SSH_OPTIONS_STRICTHOSTKEYCHECK,
SSH_OPTIONS_COMPRESSION,
SSH_OPTIONS_COMPRESSION_LEVEL,
SSH_OPTIONS_KEY_EXCHANGE,
SSH_OPTIONS_HOSTKEYS,
SSH_OPTIONS_GSSAPI_SERVER_IDENTITY,
SSH_OPTIONS_GSSAPI_CLIENT_IDENTITY,
SSH_OPTIONS_GSSAPI_DELEGATE_CREDENTIALS,
SSH_OPTIONS_HMAC_C_S,
SSH_OPTIONS_HMAC_S_C,
};
enum {
SSH_LOG_NOLOG=0, /* No logging at all */
SSH_LOG_WARNING, /* Only warnings */
SSH_LOG_PROTOCOL, /* High level protocol information */
SSH_LOG_PACKET, /* Lower level protocol informations, packet level */
SSH_LOG_FUNCTIONS /* Every function path */
};
#ifndef socket_t
typedef int socket_t;
#endif
extern ssh_session (*ssh_new)(void);
extern void (*ssh_set_blocking)(ssh_session session, int blocking);
extern int (*ssh_options_set)(ssh_session session, enum ssh_options_e type, const void *value);
extern int (*ssh_connect)(ssh_session session);
extern socket_t (*ssh_get_fd)(ssh_session session);
extern int (*ssh_is_server_known)(ssh_session session);
extern int (*ssh_userauth_publickey_auto)(ssh_session session, const char *username, const char *passphrase);
extern const char * (*ssh_get_error)(void *error);
extern int (*ssh_get_error_code)(void *error);
extern void (*ssh_disconnect)(ssh_session session);
extern void (*ssh_free)(ssh_session session);
extern ssh_channel (*ssh_channel_new)(ssh_session session);
extern int (*ssh_channel_is_open)(ssh_channel channel);
extern int (*ssh_channel_close)(ssh_channel channel);
extern void (*ssh_channel_free)(ssh_channel channel);
extern int (*ssh_channel_open_session)(ssh_channel channel);
extern int (*ssh_channel_request_subsystem)(ssh_channel channel, const char *subsystem);
extern int (*ssh_channel_read_nonblocking)(ssh_channel channel, void *dest, uint32_t count, int is_stderr);
extern int (*ssh_channel_is_eof)(ssh_channel channel);
extern int (*ssh_channel_select)(ssh_channel *readchans, ssh_channel *writechans, ssh_channel *exceptchans, struct timeval * timeout);
extern int (*ssh_channel_write)(ssh_channel channel, const void *data, uint32_t len);
const char *load_libssh(void);
#endif /* _BIRD_LIBSSH_H_ */
......@@ -31,7 +31,7 @@
struct pool {
resource r;
list inside;
char *name;
const char *name;
};
static void pool_dump(resource *);
......@@ -61,7 +61,7 @@ static int indent;
* parent pool.
*/
pool *
rp_new(pool *p, char *name)
rp_new(pool *p, const char *name)
{
pool *z = ralloc(p, &pool_class);
z->name = name;
......
......@@ -37,7 +37,7 @@ struct resclass {
typedef struct pool pool;
void resource_init(void);
pool *rp_new(pool *, char *); /* Create new pool */
pool *rp_new(pool *, const char *); /* Create new pool */
void rfree(void *); /* Free single resource */
void rdump(void *); /* Dump to debug output */
size_t rmemsize(void *res); /* Return size of memory used by the resource */
......
......@@ -12,6 +12,24 @@
#include <errno.h>
#include "lib/resource.h"
#include "lib/libssh.h"
struct ssh_sock {
const char *username; /* (Required) SSH user name */
const char *server_hostkey_path; /* (Optional) Filepath to the SSH public key of remote side, can be knownhost file */
const char *client_privkey_path; /* (Optional) Filepath to the SSH private key of BIRD */
const char *subsystem; /* (Optional) Name of SSH subsytem */
ssh_session session; /* Internal */
ssh_channel channel; /* Internal */
int state; /* Internal */
#define SK_SSH_CONNECT 0 /* Start state */
#define SK_SSH_SERVER_KNOWN 1 /* Internal */
#define SK_SSH_USERAUTH 2 /* Internal */
#define SK_SSH_CHANNEL 3 /* Internal */
#define SK_SSH_SESSION 4 /* Internal */
#define SK_SSH_SUBSYSTEM 5 /* Internal */
#define SK_SSH_ESTABLISHED 6 /* Final state */
};
typedef struct birdsock {
resource r;
......@@ -20,6 +38,7 @@ typedef struct birdsock {
int subtype; /* Socket subtype */
void *data; /* User data */
ip_addr saddr, daddr; /* IPA_NONE = unspecified */
const char *host; /* Alternative to daddr, NULL = unspecified */
uint sport, dport; /* 0 = unspecified (for IP: protocol type) */
int tos; /* TOS / traffic class, -1 = default */
int priority; /* Local socket priority, -1 = default */
......@@ -52,7 +71,8 @@ typedef struct birdsock {
node n;
void *rbuf_alloc, *tbuf_alloc;
char *password; /* Password for MD5 authentication */
char *err; /* Error message */
const char *err; /* Error message */
struct ssh_sock *ssh; /* Used in SK_SSH */
} sock;
sock *sock_new(pool *); /* Allocate new socket */
......@@ -115,6 +135,8 @@ extern int sk_priority_control; /* Suggested priority for control traffic, shou
#define SK_MAGIC 7 /* Internal use by sysdep code */
#define SK_UNIX_PASSIVE 8
#define SK_UNIX 9
#define SK_SSH_ACTIVE 10 /* - - * * - ? - DA = host */
#define SK_SSH 11
/*
* Socket subtypes
......
......@@ -1262,6 +1262,9 @@ protos_build(void)
#ifdef CONFIG_BABEL
proto_build(&proto_babel);
#endif
#ifdef CONFIG_RPKI
proto_build(&proto_rpki);
#endif
proto_pool = rp_new(&root_pool, "Protocols");
proto_shutdown_timer = tm_new(proto_pool);
......
......@@ -81,7 +81,7 @@ void protos_dump_all(void);
extern struct protocol
proto_device, proto_radv, proto_rip, proto_static,
proto_ospf, proto_pipe, proto_bgp, proto_bfd, proto_babel;
proto_ospf, proto_pipe, proto_bgp, proto_bfd, proto_babel, proto_rpki;
/*
* Routing Protocol Instance
......@@ -271,7 +271,7 @@ proto_get_router_id(struct proto_config *pc)
}
/* Moved from route.h to avoid dependency conflicts */
static inline void rte_update(struct proto *p, net_addr *n, rte *new) { rte_update2(p->main_channel, n, new, p->main_source); }
static inline void rte_update(struct proto *p, const net_addr *n, rte *new) { rte_update2(p->main_channel, n, new, p->main_source); }
extern list proto_list;
......@@ -562,11 +562,9 @@ int proto_configure_channel(struct proto *p, struct channel **c, struct channel_
void channel_set_state(struct channel *c, uint state);
/*
static inline void channel_init(struct channel *c) { channel_set_state(c, CS_START); }
static inline void channel_open(struct channel *c) { channel_set_state(c, CS_UP); }
static inline void channel_close(struct channel *c) { channel_set_state(c, CS_FLUSHING); }
*/
void channel_request_feeding(struct channel *c);
void *channel_config_new(const struct channel_class *cc, uint net_type, struct proto_config *proto);
......
......@@ -283,7 +283,7 @@ void *net_route(rtable *tab, const net_addr *n);
int net_roa_check(rtable *tab, const net_addr *n, u32 asn);
rte *rte_find(net *net, struct rte_src *src);
rte *rte_get_temp(struct rta *);
void rte_update2(struct channel *c, net_addr *n, rte *new, struct rte_src *src);
void rte_update2(struct channel *c, const net_addr *n, rte *new, struct rte_src *src);
/* rte_update() moved to protocol.h to avoid dependency conflicts */
void rte_discard(rtable *tab, rte *old);
int rt_examine(rtable *t, net_addr *a, struct proto *p, struct filter *filter);
......@@ -384,6 +384,8 @@ typedef struct rta {
#define RTS_BGP 11 /* BGP route */
#define RTS_PIPE 12 /* Inter-table wormhole */
#define RTS_BABEL 13 /* Babel route */
#define RTS_RPKI 14 /* Route Origin Authorization */
#define RTC_UNICAST 0
#define RTC_BROADCAST 1
......@@ -561,6 +563,7 @@ extern struct protocol *attr_class_to_protocol[EAP_MAX];
#define DEF_PREF_BABEL 130 /* Babel */
#define DEF_PREF_RIP 120 /* RIP */
#define DEF_PREF_BGP 100 /* BGP */
#define DEF_PREF_RPKI 100 /* RPKI */
#define DEF_PREF_INHERITED 10 /* Routes inherited from other routing daemons */
/*
......
......@@ -1291,7 +1291,7 @@ rte_unhide_dummy_routes(net *net, rte **dummy)
*/
void
rte_update2(struct channel *c, net_addr *n, rte *new, struct rte_src *src)
rte_update2(struct channel *c, const net_addr *n, rte *new, struct rte_src *src)
{
struct proto *p = c->proto;
struct proto_stats *stats = &c->stats;
......
......@@ -4,7 +4,8 @@ C bfd
C bgp
C ospf
C pipe
C rip
C radv
C rip
C rpki
C static
S ../nest/rt-dev.c
S rpki.c
S packets.c
S transport.c
S tcp_transport.c
S ssh_transport.c
src := rpki.c packets.c tcp_transport.c ssh_transport.c transport.c
obj := $(src-o-files)
$(all-daemon)
$(cf-local)
/*
* BIRD -- The Resource Public Key Infrastructure (RPKI) to Router Protocol
*
* (c) 2015 CZ.NIC
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
CF_HDR
#include "proto/rpki/rpki.h"
CF_DEFINES
#define RPKI_CFG ((struct rpki_config *) this_proto)
#define RPKI_TR_SSH_CFG ((struct rpki_tr_ssh_config *) RPKI_CFG->tr_config.spec)
static void
rpki_check_unused_hostname(void)
{
if (RPKI_CFG->hostname != NULL)
cf_error("Only one cache server per protocol allowed");
}
static void
rpki_check_unused_transport(void)
{
if (RPKI_CFG->tr_config.spec != NULL)
cf_error("At the most one transport per protocol allowed");
}
CF_DECLS
CF_KEYWORDS(RPKI, REMOTE, BIRD, PRIVATE, PUBLIC, KEY, TCP, SSH, TRANSPORT, USER,
RETRY, REFRESH, EXPIRE, KEEP)
%type <i> rpki_keep_interval
CF_GRAMMAR
CF_ADDTO(proto, rpki_proto)
rpki_proto_start: proto_start RPKI {
this_proto = proto_config_new(&proto_rpki, $1);
RPKI_CFG->retry_interval = RPKI_RETRY_INTERVAL;
RPKI_CFG->refresh_interval = RPKI_REFRESH_INTERVAL;
RPKI_CFG->expire_interval = RPKI_EXPIRE_INTERVAL;
};
rpki_proto: rpki_proto_start proto_name '{' rpki_proto_opts '}' { rpki_check_config(RPKI_CFG); };
rpki_proto_opts:
/* empty */
| rpki_proto_opts rpki_proto_item ';'
;
rpki_proto_item:
proto_item
| proto_channel
| REMOTE rpki_cache_addr
| REMOTE rpki_cache_addr rpki_proto_item_port
| rpki_proto_item_port
| TRANSPORT rpki_transport
| REFRESH rpki_keep_interval expr {
if (rpki_check_refresh_interval($3))
cf_error(rpki_check_refresh_interval($3));
RPKI_CFG->refresh_interval = $3;
RPKI_CFG->keep_refresh_interval = $2;
}
| RETRY rpki_keep_interval expr {
if (rpki_check_retry_interval($3))
cf_error(rpki_check_retry_interval($3));
RPKI_CFG->retry_interval = $3;
RPKI_CFG->keep_retry_interval = $2;
}
| EXPIRE rpki_keep_interval expr {
if (rpki_check_expire_interval($3))
cf_error(rpki_check_expire_interval($3));
RPKI_CFG->expire_interval = $3;
RPKI_CFG->keep_expire_interval = $2;