Skip to content

Commit

Permalink
Live PRKI Origin Validation Annotation
Browse files Browse the repository at this point in the history
- The BGPStream will be extended by Live PRKI Origin Validation
Annotation

- All details concerning the provided functions, annotation elements
and output format are described in issue #19 and
/pull/26 (update)
  • Loading branch information
Samir Al-Sheikh authored and salsh committed May 6, 2017
1 parent f4f81ea commit 60232ad
Show file tree
Hide file tree
Showing 18 changed files with 1,004 additions and 9 deletions.
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

0 comments on commit 60232ad

Please sign in to comment.