Skip to content

Commit 60232ad

Browse files
Samir Al-Sheikhsalsh
authored andcommitted
Live PRKI Origin Validation Annotation
- 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)
1 parent f4f81ea commit 60232ad

18 files changed

+1004
-9
lines changed

configure.ac

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,43 @@ AC_DEFINE_UNQUOTED([ED_PLUGIN_INIT_ALL_ENABLED], $ED_PLUGIN_INIT_ALL_ENABLED,
262262

263263
AC_MSG_NOTICE([----------------------------------])
264264

265+
# RTR configuration
266+
AC_MSG_CHECKING([whether the RTR library is available])
267+
AC_ARG_WITH([rtr],
268+
[AS_HELP_STRING([--without-rtr],
269+
[do not compile with rtr support])],
270+
[],
271+
[with_rtr=yes])
272+
AM_CONDITIONAL([WITH_rtr], [test "x$with_rtr" != xno])
273+
if test x"$with_rtr" = xyes; then
274+
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include "rtrlib/rtrlib.h"]])],
275+
[AC_MSG_RESULT(yes)
276+
AC_DEFINE([WITH_RTR],[1],[Building with RTR support])],
277+
AC_MSG_RESULT(no)
278+
)
279+
else
280+
AC_MSG_RESULT([no])
281+
fi
282+
283+
# SSH configuration
284+
AC_MSG_CHECKING([whether the RTR library is compiled with SSH])
285+
AC_ARG_WITH([ssh],
286+
[AS_HELP_STRING([--without-ssh],
287+
[do not compile with ssh support])],
288+
[],
289+
[with_ssh=yes])
290+
AM_CONDITIONAL([WITH_ssh], [test "x$with_ssh" != xno])
291+
if test x"$with_ssh" = xyes; then
292+
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include "rtrlib/rtrlib.h"]],
293+
[[struct tr_ssh_config config;]])],
294+
[AC_MSG_RESULT(yes)
295+
AC_DEFINE([WITH_SSH],[1],[Building with SSH support])],
296+
AC_MSG_RESULT(no)
297+
)
298+
else
299+
AC_MSG_RESULT([no])
300+
fi
301+
265302
# we may want to come back later and add compile-time configuration for things
266303
# like datastructure providers, but for now it will all get compiled
267304

lib/bgpstream.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,11 @@ bgpstream_t *bgpstream_create() {
199199
bs = NULL;
200200
return NULL;
201201
}
202+
203+
#ifdef WITH_RTR
204+
bs->rtr_server_conf.active = 0;
205+
#endif
206+
202207
/* memory for the bgpstream interface has been
203208
* allocated correctly */
204209
bs->status = BGPSTREAM_STATUS_ALLOCATED;
@@ -401,13 +406,46 @@ void bgpstream_set_live_mode(bgpstream_t *bs) {
401406
bgpstream_debug("BS: set_blocking stop");
402407
}
403408

409+
#ifdef WITH_RTR
410+
/* Get the RTR-Socket & configuration
411+
*/
412+
struct rtr_mgr_config *bgpstream_get_rtr_config(bgpstream_t *bs)
413+
{
414+
return bs->cfg_tr;
415+
}
416+
417+
/* Set the RTR-Configuration
418+
*/
419+
int bgpstream_set_rtr_config(bgpstream_t *bs, char *host, char *port, char *ssh_user,
420+
char *ssh_hostkey, char *ssh_privatekey,
421+
int active)
422+
{
423+
424+
bs->rtr_server_conf.host = host;
425+
bs->rtr_server_conf.port = port;
426+
bs->rtr_server_conf.ssh_user = ssh_user;
427+
bs->rtr_server_conf.ssh_hostkey = ssh_hostkey;
428+
bs->rtr_server_conf.ssh_privatekey = ssh_privatekey;
429+
bs->rtr_server_conf.active = active;
430+
return 0;
431+
}
432+
#endif
404433

405434
/* turn on the bgpstream interface, i.e.:
406435
* it makes the interface ready
407436
* for a new get next call
437+
* it starts the RTR-Connection for validation if RTR is active
408438
*/
409439
int bgpstream_start(bgpstream_t *bs) {
410440
bgpstream_debug("BS: init start");
441+
#ifdef WITH_RTR
442+
if (bs->rtr_server_conf.active) {
443+
bs->cfg_tr = bgpstream_rtr_start_connection(
444+
bs->rtr_server_conf.host, bs->rtr_server_conf.port, NULL, NULL, NULL,
445+
bs->rtr_server_conf.ssh_user, bs->rtr_server_conf.ssh_hostkey,
446+
bs->rtr_server_conf.ssh_privatekey);
447+
}
448+
#endif
411449
if(bs == NULL || (bs != NULL && bs->status != BGPSTREAM_STATUS_ALLOCATED)) {
412450
return 0; // nothing to init
413451
}
@@ -492,6 +530,12 @@ int bgpstream_get_next_record(bgpstream_t *bs,
492530
/* turn off the bgpstream interface */
493531
void bgpstream_stop(bgpstream_t *bs) {
494532
bgpstream_debug("BS: close start");
533+
#ifdef WITH_RTR
534+
if (bs->rtr_server_conf.active) {
535+
bgpstream_rtr_close_connection(bs->cfg_tr);
536+
bs->rtr_server_conf.active = false;
537+
}
538+
#endif
495539
if(bs == NULL || (bs != NULL && bs->status != BGPSTREAM_STATUS_ON)) {
496540
return; // nothing to close
497541
}

lib/bgpstream.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,13 +146,37 @@ typedef struct struct_bgpstream_data_interface_option
146146

147147
} bgpstream_data_interface_option_t;
148148

149+
#ifdef WITH_RTR
150+
149151
/** @} */
150152

151153
/**
152154
* @name Public API Functions
153155
*
154156
* @{ */
155157

158+
/** Get the configuration of the RTR-Socket-Manager
159+
*
160+
* @return a pointer to the configuration of the rtr-socket-manager
161+
*/
162+
struct rtr_mgr_config *bgpstream_get_rtr_config();
163+
164+
/** Set the configuration of the RTR-Socket-Manager
165+
*
166+
* @param bs a pointer to a BGP Stream instance
167+
* @param host the host of the cache server
168+
* @param port the port of the cache server
169+
* @param ssh_user the username for a SSH connection
170+
* @param ssh_hostkey the hostkey for a SSH connection
171+
* @param ssh_privatekey the private key for a SSH connection
172+
* @param active whether the rtr-validation is enabled
173+
*/
174+
int bgpstream_set_rtr_config(bgpstream_t *bs,
175+
char *host, char *port, char *ssh_user,
176+
char *ssh_hostkey, char *ssh_privatekey,
177+
int active);
178+
#endif
179+
156180
/** Create a new BGP Stream instance
157181
*
158182
* @return a pointer to a BGP Stream instance if successful, NULL otherwise

lib/bgpstream_constants.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@
3030
// dump name max length
3131
#define BGPSTREAM_DUMP_MAX_LEN 1024
3232

33+
// RPKI validation result max length
34+
#define BGPSTREAM_RPKI_RST_MAX_LEN 2048
35+
36+
// RPKI validation result max ROA entries
37+
#define BGPSTREAM_RPKI_MAX__ROA_ENT 16
38+
3339
// parameters/attribute/filters max length
3440
#define BGPSTREAM_PAR_MAX_LEN 512
3541

lib/bgpstream_elem.c

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,17 @@
3030

3131
#include "bgpdump_lib.h"
3232
#include "utils.h"
33+
#include "khash.h"
3334

35+
#include "bgpstream.h"
3436
#include "bgpstream_utils.h"
3537

3638
#include "bgpstream_debug.h"
3739
#include "bgpstream_record.h"
3840

41+
#include "bgpstream_constants.h"
3942
#include "bgpstream_elem_int.h"
43+
#include "bgpstream_utils_rtr.h"
4044

4145
/* ==================== PROTECTED FUNCTIONS ==================== */
4246

@@ -81,12 +85,25 @@ void bgpstream_elem_destroy(bgpstream_elem_t *elem) {
8185
bgpstream_community_set_destroy(elem->communities);
8286
elem->communities = NULL;
8387

88+
#ifdef WITH_RTR
89+
if(elem->annotations.active){
90+
kh_destroy(rpki_result, elem->annotations.rpki_kh);
91+
elem->annotations.rpki_kh = NULL;
92+
}
93+
#endif
94+
8495
free(elem);
8596
}
8697

8798
void bgpstream_elem_clear(bgpstream_elem_t *elem) {
8899
bgpstream_as_path_clear(elem->aspath);
89100
bgpstream_community_set_clear(elem->communities);
101+
#ifdef WITH_RTR
102+
if(elem->annotations.active &&
103+
(elem->annotations.rpki_validation_status != BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_NOTVALIDATED)){
104+
kh_clear(rpki_result, elem->annotations.rpki_kh);
105+
}
106+
#endif
90107
}
91108

92109
bgpstream_elem_t *bgpstream_elem_copy(bgpstream_elem_t *dst,
@@ -346,6 +363,17 @@ char *bgpstream_elem_custom_snprintf(char *buf, size_t len,
346363
if(B_FULL)
347364
return NULL;
348365

366+
#ifdef WITH_RTR
367+
/* RPKI Validation */
368+
if(elem->annotations.active) {
369+
char buf_rpki[BGPSTREAM_RPKI_RST_MAX_LEN];
370+
c = bgpstream_elem_get_rpki_validation_result_snprintf(
371+
buf_rpki, sizeof(buf_rpki), elem);
372+
strcat(buf, buf_rpki);
373+
written += c;
374+
buf_p += c;
375+
}
376+
#endif
349377
/* END OF LINE */
350378
break;
351379

@@ -422,3 +450,99 @@ char *bgpstream_elem_snprintf(char *buf, size_t len,
422450
{
423451
return bgpstream_elem_custom_snprintf(buf, len, elem, 1);
424452
}
453+
454+
#ifdef WITH_RTR
455+
int bgpstream_elem_get_rpki_validation_result_snprintf(
456+
char *buf, size_t len, bgpstream_elem_t const *elem)
457+
{
458+
int key;
459+
char *val;
460+
char result_output[BGPSTREAM_RPKI_RST_MAX_LEN];
461+
char valid_prefixes[BGPSTREAM_RPKI_RST_MAX_LEN];
462+
if (elem->annotations.rpki_validation_status !=
463+
BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_NOTFOUND) {
464+
snprintf(result_output, sizeof(result_output), "%s%s", result_output,
465+
elem->annotations.rpki_validation_status ==
466+
BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_INVALID
467+
? "invalid;" : "valid;");
468+
469+
kh_foreach(elem->annotations.rpki_kh, key, val,
470+
snprintf(valid_prefixes, sizeof(valid_prefixes), "%i,%s;", key, val);
471+
strcat(result_output, valid_prefixes);
472+
);
473+
result_output[strlen(result_output) - 1] = 0;
474+
} else {
475+
snprintf(result_output, sizeof(result_output), "%s%s", result_output,
476+
"notfound");
477+
}
478+
479+
return snprintf(buf, len, "%s", result_output);
480+
}
481+
482+
void bgpstream_elem_get_rpki_validation_result(struct rtr_mgr_config *cfg, bgpstream_elem_t *elem,
483+
char *prefix,
484+
uint32_t origin_asn,
485+
uint8_t mask_len)
486+
{
487+
if (elem->annotations.rpki_validation_status ==
488+
BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_NOTVALIDATED) {
489+
490+
struct reasoned_result res_reasoned =
491+
bgpstream_rtr_validate_reason(cfg, origin_asn, prefix, mask_len);
492+
493+
if (res_reasoned.result == BGP_PFXV_STATE_VALID) {
494+
elem->annotations.rpki_validation_status =
495+
BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_VALID;
496+
}
497+
if (res_reasoned.result == BGP_PFXV_STATE_NOT_FOUND) {
498+
elem->annotations.rpki_validation_status =
499+
BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_NOTFOUND;
500+
}
501+
if (res_reasoned.result == BGP_PFXV_STATE_INVALID) {
502+
elem->annotations.rpki_validation_status =
503+
BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_INVALID;
504+
}
505+
506+
if (elem->annotations.rpki_validation_status !=
507+
BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_NOTFOUND) {
508+
509+
char reason_prefix[INET6_ADDRSTRLEN];
510+
char buf_p[BGPSTREAM_RPKI_RST_MAX_LEN];
511+
512+
int ret;
513+
khiter_t k;
514+
515+
if(elem->annotations.khash_init != 1) {
516+
elem->annotations.rpki_kh = kh_init(rpki_result);
517+
elem->annotations.khash_init = 1;
518+
}
519+
520+
for (int i = 0; i < res_reasoned.reason_len; i++) {
521+
if(kh_get(rpki_result, elem->annotations.rpki_kh, res_reasoned.reason[i].asn) ==
522+
kh_end(elem->annotations.rpki_kh)){
523+
k = kh_put(rpki_result, elem->annotations.rpki_kh, (int) res_reasoned.reason[i].asn, &ret);
524+
kh_val(elem->annotations.rpki_kh, k) = '\0';
525+
}
526+
else {
527+
k = kh_get(rpki_result, elem->annotations.rpki_kh, (int) res_reasoned.reason[i].asn);
528+
}
529+
530+
lrtr_ip_addr_to_str(&(res_reasoned.reason[i].prefix), reason_prefix, sizeof(reason_prefix));
531+
snprintf(elem->annotations.valid_prefix[k], BGPSTREAM_RPKI_RST_MAX_LEN, "%s/%" PRIu8 "-%"PRIu8,
532+
reason_prefix, res_reasoned.reason[i].min_len, res_reasoned.reason[i].max_len);
533+
534+
if(!kh_val(elem->annotations.rpki_kh, k)){
535+
kh_val(elem->annotations.rpki_kh, k) = elem->annotations.valid_prefix[k];
536+
}
537+
else if(!strstr(kh_val(elem->annotations.rpki_kh, k), elem->annotations.valid_prefix[k])) {
538+
snprintf(buf_p, sizeof(buf_p), "%s %s", kh_val(elem->annotations.rpki_kh, k),
539+
elem->annotations.valid_prefix[k]);
540+
kh_val(elem->annotations.rpki_kh, k) = buf_p;
541+
}
542+
}
543+
}
544+
545+
free(res_reasoned.reason);
546+
}
547+
}
548+
#endif

0 commit comments

Comments
 (0)