diff options
Diffstat (limited to 'proto/rpki/rpki.h')
-rw-r--r-- | proto/rpki/rpki.h | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/proto/rpki/rpki.h b/proto/rpki/rpki.h new file mode 100644 index 00000000..8972b33a --- /dev/null +++ b/proto/rpki/rpki.h @@ -0,0 +1,165 @@ +/* + * 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_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 */ + btime last_update; /* Last successful synchronization with cache server */ + btime last_rx_prefix; /* Last received prefix PDU */ + + /* Intervals can be changed by cache server on the fly */ + u32 refresh_interval; /* Actual refresh interval (in seconds) */ + 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_ */ |