Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Live PRKI Origin Validation Annotation #26

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,43 @@ AC_DEFINE_UNQUOTED([ED_PLUGIN_INIT_ALL_ENABLED], $ED_PLUGIN_INIT_ALL_ENABLED,

AC_MSG_NOTICE([----------------------------------])

# RTR configuration
AC_MSG_CHECKING([whether the RTR library is available])
AC_ARG_WITH([rtr],
[AS_HELP_STRING([--without-rtr],
[do not compile with rtr support])],
[],
[with_rtr=yes])
AM_CONDITIONAL([WITH_rtr], [test "x$with_rtr" != xno])
if test x"$with_rtr" = xyes; then
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include "rtrlib/rtrlib.h"]])],
[AC_MSG_RESULT(yes)
AC_DEFINE([WITH_RTR],[1],[Building with RTR support])],
AC_MSG_RESULT(no)
)
else
AC_MSG_RESULT([no])
fi

# SSH configuration
AC_MSG_CHECKING([whether the RTR library is compiled with SSH])
AC_ARG_WITH([ssh],
[AS_HELP_STRING([--without-ssh],
[do not compile with ssh support])],
[],
[with_ssh=yes])
AM_CONDITIONAL([WITH_ssh], [test "x$with_ssh" != xno])
if test x"$with_ssh" = xyes; then
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include "rtrlib/rtrlib.h"]],
[[struct tr_ssh_config config;]])],
[AC_MSG_RESULT(yes)
AC_DEFINE([WITH_SSH],[1],[Building with SSH support])],
AC_MSG_RESULT(no)
)
else
AC_MSG_RESULT([no])
fi

# we may want to come back later and add compile-time configuration for things
# like datastructure providers, but for now it will all get compiled

Expand Down
44 changes: 44 additions & 0 deletions lib/bgpstream.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,11 @@ bgpstream_t *bgpstream_create() {
bs = NULL;
return NULL;
}

#ifdef WITH_RTR
bs->rtr_server_conf.active = 0;
#endif

/* memory for the bgpstream interface has been
* allocated correctly */
bs->status = BGPSTREAM_STATUS_ALLOCATED;
Expand Down Expand Up @@ -401,13 +406,46 @@ void bgpstream_set_live_mode(bgpstream_t *bs) {
bgpstream_debug("BS: set_blocking stop");
}

#ifdef WITH_RTR
/* Get the RTR-Socket & configuration
*/
struct rtr_mgr_config *bgpstream_get_rtr_config(bgpstream_t *bs)
{
return bs->cfg_tr;
}

/* Set the RTR-Configuration
*/
int bgpstream_set_rtr_config(bgpstream_t *bs, char *host, char *port, char *ssh_user,
char *ssh_hostkey, char *ssh_privatekey,
int active)
{

bs->rtr_server_conf.host = host;
bs->rtr_server_conf.port = port;
bs->rtr_server_conf.ssh_user = ssh_user;
bs->rtr_server_conf.ssh_hostkey = ssh_hostkey;
bs->rtr_server_conf.ssh_privatekey = ssh_privatekey;
bs->rtr_server_conf.active = active;
return 0;
}
#endif

/* turn on the bgpstream interface, i.e.:
* it makes the interface ready
* for a new get next call
* it starts the RTR-Connection for validation if RTR is active
*/
int bgpstream_start(bgpstream_t *bs) {
bgpstream_debug("BS: init start");
#ifdef WITH_RTR
if (bs->rtr_server_conf.active) {
bs->cfg_tr = bgpstream_rtr_start_connection(
bs->rtr_server_conf.host, bs->rtr_server_conf.port, NULL, NULL, NULL,
bs->rtr_server_conf.ssh_user, bs->rtr_server_conf.ssh_hostkey,
bs->rtr_server_conf.ssh_privatekey);
}
#endif
if(bs == NULL || (bs != NULL && bs->status != BGPSTREAM_STATUS_ALLOCATED)) {
return 0; // nothing to init
}
Expand Down Expand Up @@ -492,6 +530,12 @@ int bgpstream_get_next_record(bgpstream_t *bs,
/* turn off the bgpstream interface */
void bgpstream_stop(bgpstream_t *bs) {
bgpstream_debug("BS: close start");
#ifdef WITH_RTR
if (bs->rtr_server_conf.active) {
bgpstream_rtr_close_connection(bs->cfg_tr);
bs->rtr_server_conf.active = false;
}
#endif
if(bs == NULL || (bs != NULL && bs->status != BGPSTREAM_STATUS_ON)) {
return; // nothing to close
}
Expand Down
24 changes: 24 additions & 0 deletions lib/bgpstream.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,37 @@ typedef struct struct_bgpstream_data_interface_option

} bgpstream_data_interface_option_t;

#ifdef WITH_RTR

/** @} */

/**
* @name Public API Functions
*
* @{ */

/** Get the configuration of the RTR-Socket-Manager
*
* @return a pointer to the configuration of the rtr-socket-manager
*/
struct rtr_mgr_config *bgpstream_get_rtr_config();

/** Set the configuration of the RTR-Socket-Manager
*
* @param bs a pointer to a BGP Stream instance
* @param host the host of the cache server
* @param port the port of the cache server
* @param ssh_user the username for a SSH connection
* @param ssh_hostkey the hostkey for a SSH connection
* @param ssh_privatekey the private key for a SSH connection
* @param active whether the rtr-validation is enabled
*/
int bgpstream_set_rtr_config(bgpstream_t *bs,
char *host, char *port, char *ssh_user,
char *ssh_hostkey, char *ssh_privatekey,
int active);
#endif

/** Create a new BGP Stream instance
*
* @return a pointer to a BGP Stream instance if successful, NULL otherwise
Expand Down
6 changes: 6 additions & 0 deletions lib/bgpstream_constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@
// dump name max length
#define BGPSTREAM_DUMP_MAX_LEN 1024

// RPKI validation result max length
#define BGPSTREAM_RPKI_RST_MAX_LEN 2048

// RPKI validation result max ROA entries
#define BGPSTREAM_RPKI_MAX__ROA_ENT 16

// parameters/attribute/filters max length
#define BGPSTREAM_PAR_MAX_LEN 512

Expand Down
124 changes: 124 additions & 0 deletions lib/bgpstream_elem.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,17 @@

#include "bgpdump_lib.h"
#include "utils.h"
#include "khash.h"

#include "bgpstream.h"
#include "bgpstream_utils.h"

#include "bgpstream_debug.h"
#include "bgpstream_record.h"

#include "bgpstream_constants.h"
#include "bgpstream_elem_int.h"
#include "bgpstream_utils_rtr.h"

/* ==================== PROTECTED FUNCTIONS ==================== */

Expand Down Expand Up @@ -81,12 +85,25 @@ void bgpstream_elem_destroy(bgpstream_elem_t *elem) {
bgpstream_community_set_destroy(elem->communities);
elem->communities = NULL;

#ifdef WITH_RTR
if(elem->annotations.active){
kh_destroy(rpki_result, elem->annotations.rpki_kh);
elem->annotations.rpki_kh = NULL;
}
#endif

free(elem);
}

void bgpstream_elem_clear(bgpstream_elem_t *elem) {
bgpstream_as_path_clear(elem->aspath);
bgpstream_community_set_clear(elem->communities);
#ifdef WITH_RTR
if(elem->annotations.active &&
(elem->annotations.rpki_validation_status != BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_NOTVALIDATED)){
kh_clear(rpki_result, elem->annotations.rpki_kh);
}
#endif
}

bgpstream_elem_t *bgpstream_elem_copy(bgpstream_elem_t *dst,
Expand Down Expand Up @@ -346,6 +363,17 @@ char *bgpstream_elem_custom_snprintf(char *buf, size_t len,
if(B_FULL)
return NULL;

#ifdef WITH_RTR
/* RPKI Validation */
if(elem->annotations.active) {
char buf_rpki[BGPSTREAM_RPKI_RST_MAX_LEN];
c = bgpstream_elem_get_rpki_validation_result_snprintf(
buf_rpki, sizeof(buf_rpki), elem);
strcat(buf, buf_rpki);
written += c;
buf_p += c;
}
#endif
/* END OF LINE */
break;

Expand Down Expand Up @@ -422,3 +450,99 @@ char *bgpstream_elem_snprintf(char *buf, size_t len,
{
return bgpstream_elem_custom_snprintf(buf, len, elem, 1);
}

#ifdef WITH_RTR
int bgpstream_elem_get_rpki_validation_result_snprintf(
char *buf, size_t len, bgpstream_elem_t const *elem)
{
int key;
char *val;
char result_output[BGPSTREAM_RPKI_RST_MAX_LEN];
char valid_prefixes[BGPSTREAM_RPKI_RST_MAX_LEN];
if (elem->annotations.rpki_validation_status !=
BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_NOTFOUND) {
snprintf(result_output, sizeof(result_output), "%s%s", result_output,
elem->annotations.rpki_validation_status ==
BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_INVALID
? "invalid;" : "valid;");

kh_foreach(elem->annotations.rpki_kh, key, val,
snprintf(valid_prefixes, sizeof(valid_prefixes), "%i,%s;", key, val);
strcat(result_output, valid_prefixes);
);
result_output[strlen(result_output) - 1] = 0;
} else {
snprintf(result_output, sizeof(result_output), "%s%s", result_output,
"notfound");
}

return snprintf(buf, len, "%s", result_output);
}

void bgpstream_elem_get_rpki_validation_result(struct rtr_mgr_config *cfg, bgpstream_elem_t *elem,
char *prefix,
uint32_t origin_asn,
uint8_t mask_len)
{
if (elem->annotations.rpki_validation_status ==
BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_NOTVALIDATED) {

struct reasoned_result res_reasoned =
bgpstream_rtr_validate_reason(cfg, origin_asn, prefix, mask_len);

if (res_reasoned.result == BGP_PFXV_STATE_VALID) {
elem->annotations.rpki_validation_status =
BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_VALID;
}
if (res_reasoned.result == BGP_PFXV_STATE_NOT_FOUND) {
elem->annotations.rpki_validation_status =
BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_NOTFOUND;
}
if (res_reasoned.result == BGP_PFXV_STATE_INVALID) {
elem->annotations.rpki_validation_status =
BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_INVALID;
}

if (elem->annotations.rpki_validation_status !=
BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_NOTFOUND) {

char reason_prefix[INET6_ADDRSTRLEN];
char buf_p[BGPSTREAM_RPKI_RST_MAX_LEN];

int ret;
khiter_t k;

if(elem->annotations.khash_init != 1) {
elem->annotations.rpki_kh = kh_init(rpki_result);
elem->annotations.khash_init = 1;
}

for (int i = 0; i < res_reasoned.reason_len; i++) {
if(kh_get(rpki_result, elem->annotations.rpki_kh, res_reasoned.reason[i].asn) ==
kh_end(elem->annotations.rpki_kh)){
k = kh_put(rpki_result, elem->annotations.rpki_kh, (int) res_reasoned.reason[i].asn, &ret);
kh_val(elem->annotations.rpki_kh, k) = '\0';
}
else {
k = kh_get(rpki_result, elem->annotations.rpki_kh, (int) res_reasoned.reason[i].asn);
}

lrtr_ip_addr_to_str(&(res_reasoned.reason[i].prefix), reason_prefix, sizeof(reason_prefix));
snprintf(elem->annotations.valid_prefix[k], BGPSTREAM_RPKI_RST_MAX_LEN, "%s/%" PRIu8 "-%"PRIu8,
reason_prefix, res_reasoned.reason[i].min_len, res_reasoned.reason[i].max_len);

if(!kh_val(elem->annotations.rpki_kh, k)){
kh_val(elem->annotations.rpki_kh, k) = elem->annotations.valid_prefix[k];
}
else if(!strstr(kh_val(elem->annotations.rpki_kh, k), elem->annotations.valid_prefix[k])) {
snprintf(buf_p, sizeof(buf_p), "%s %s", kh_val(elem->annotations.rpki_kh, k),
elem->annotations.valid_prefix[k]);
kh_val(elem->annotations.rpki_kh, k) = buf_p;
}
}
}

free(res_reasoned.reason);
}
}
#endif
Loading