bird/proto/rpki/rpki.h
Pavel Tvrdík 65d2a88dd2 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";
    };
  }
  ...
2016-12-07 09:35:24 +01:00

167 lines
5.6 KiB
C

/*
* BIRD -- The Resource Public Key Infrastructure (RPKI) to Router Protocol
*
* (c) 2015 CZ.NIC
* (c) 2015 Pavel Tvrdik <pawel.tvrdik@gmail.com>
*
* Using RTRlib: http://rpki.realmv6.org/
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
#ifndef _BIRD_RPKI_H_
#define _BIRD_RPKI_H_
#include "nest/bird.h"
#include "nest/route.h"
#include "nest/protocol.h"
#include "lib/socket.h"
#include "lib/ip.h"
#include "transport.h"
#include "packets.h"
#define RPKI_TCP_PORT 323
#define RPKI_SSH_PORT 22
#define RPKI_RETRY_INTERVAL 600
#define RPKI_REFRESH_INTERVAL 3600
#define RPKI_EXPIRE_INTERVAL 7200
#define RPKI_VERSION_0 0
#define RPKI_VERSION_1 1
#define RPKI_MIN_VERSION RPKI_VERSION_0
#define RPKI_MAX_VERSION RPKI_VERSION_1
/*
* RPKI Cache
*/
enum rpki_cache_state {
RPKI_CS_CONNECTING, /* Socket is establishing the transport connection. */
RPKI_CS_ESTABLISHED, /* Connection is established, socket is waiting for a Serial Notify or expiration of the refresh_interval timer */
RPKI_CS_RESET, /* Resetting RTR connection. */
RPKI_CS_SYNC_START, /* Sending a Serial/Reset Query PDU and expecting a Cache Response PDU */
RPKI_CS_SYNC_RUNNING, /* Receiving validation records from the RTR server. A state between Cache Response PDU and End of Data PDU */
RPKI_CS_FAST_RECONNECT, /* Reconnect without any waiting period */
RPKI_CS_NO_INCR_UPDATE_AVAIL, /* Server is unable to answer the last Serial Query and sent Cache Reset. */
RPKI_CS_ERROR_NO_DATA_AVAIL, /* Server is unable to answer either a Serial Query or a Reset Query because it has no useful data available at this time. */
RPKI_CS_ERROR_FATAL, /* Fatal protocol error occurred. */
RPKI_CS_ERROR_TRANSPORT, /* Error on the transport socket occurred. */
RPKI_CS_SHUTDOWN, /* RTR Socket is stopped. */
};
struct rpki_cache {
pool *pool; /* Pool containing cache objects */
struct rpki_proto *p;
struct rpki_tr_sock *tr_sock; /* Transport specific socket */
enum rpki_cache_state state; /* RPKI_CS_* */
u32 session_id;
u8 request_session_id; /* 1: have to request new session id; 0: we have already received session id */
u32 serial_num; /* Serial number denotes the logical version of data from cache server */
u8 version; /* Protocol version */
bird_clock_t last_update; /* Last successful synchronization with cache server */
bird_clock_t last_rx_prefix; /* Last received prefix PDU */
/* Intervals can be changed by cache server on the fly */
u32 refresh_interval; /* Actual refresh interval */
u32 retry_interval;
u32 expire_interval;
timer *retry_timer; /* Retry timer event */
timer *refresh_timer; /* Refresh timer event */
timer *expire_timer; /* Expire timer event */
};
const char *rpki_get_cache_ident(struct rpki_cache *cache);
const char *rpki_cache_state_to_str(enum rpki_cache_state state);
/*
* Routes handling
*/
void rpki_table_add_roa(struct rpki_cache *cache, struct channel *channel, const net_addr_union *pfxr);
void rpki_table_remove_roa(struct rpki_cache *cache, struct channel *channel, const net_addr_union *pfxr);
/*
* RPKI Protocol Logic
*/
void rpki_cache_change_state(struct rpki_cache *cache, const enum rpki_cache_state new_state);
/*
* RPKI Timer Events
*/
const char *rpki_check_refresh_interval(uint seconds);
const char *rpki_check_retry_interval(uint seconds);
const char *rpki_check_expire_interval(uint seconds);
/*
* RPKI Protocol Configuration
*/
struct rpki_proto {
struct proto p;
struct rpki_cache *cache;
struct channel *roa4_channel;
struct channel *roa6_channel;
u8 refresh_channels; /* For non-incremental updates using rt_refresh_begin(), rt_refresh_end() */
};
struct rpki_config {
struct proto_config c;
const char *hostname; /* Full domain name or stringified IP address of cache server */
ip_addr ip; /* IP address of cache server or IPA_NONE */
u16 port; /* Port number of cache server */
struct rpki_tr_config tr_config; /* Specific transport configuration structure */
u32 refresh_interval; /* Time interval (in seconds) for periodical downloading data from cache server */
u32 retry_interval; /* Time interval (in seconds) for an unreachable server */
u32 expire_interval; /* Maximal lifetime (in seconds) of ROAs without any successful refreshment */
u8 keep_refresh_interval:1; /* Do not overwrite refresh interval by cache server update */
u8 keep_retry_interval:1; /* Do not overwrite retry interval by cache server update */
u8 keep_expire_interval:1; /* Do not overwrite expire interval by cache server update */
};
void rpki_check_config(struct rpki_config *cf);
/*
* Logger
*/
#define RPKI_LOG(log_level, rpki, msg, args...) \
do { \
log(log_level "%s: " msg, (rpki)->p.name , ## args); \
} while(0)
#if defined(LOCAL_DEBUG) || defined(GLOBAL_DEBUG)
#define CACHE_DBG(cache,msg,args...) \
do { \
RPKI_LOG(L_DEBUG, (cache)->p, "%s [%s] %s " msg, rpki_get_cache_ident(cache), rpki_cache_state_to_str((cache)->state), __func__, ## args); \
} while(0)
#else
#define CACHE_DBG(cache,msg,args...) do { } while(0)
#endif
#define RPKI_TRACE(level,rpki,msg,args...) \
do { \
if ((rpki)->p.debug & level) \
RPKI_LOG(L_TRACE, rpki, msg, ## args); \
} while(0)
#define CACHE_TRACE(level,cache,msg,args...) \
do { \
if ((cache)->p->p.debug & level) \
RPKI_LOG(L_TRACE, (cache)->p, msg, ## args); \
} while(0)
#define RPKI_WARN(p, msg, args...) RPKI_LOG(L_WARN, p, msg, ## args);
#endif /* _BIRD_RPKI_H_ */