Skip to content

Commit d9ad3cc

Browse files
author
Samir Al-Sheikh
committed
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
1 parent f4f81ea commit d9ad3cc

15 files changed

+1123
-6
lines changed

configure.ac

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

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

265+
AC_MSG_CHECKING([whether the RTR library is available])
266+
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include "rtrlib/rtrlib.h"]])],
267+
[AC_MSG_RESULT(yes)
268+
AC_DEFINE(FOUND_RTR,,found_rtr)],
269+
AC_MSG_RESULT(no)
270+
)
271+
272+
AC_MSG_CHECKING([whether the RTR library is compiled with SSH])
273+
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include "rtrlib/rtrlib.h"]],
274+
[[struct tr_ssh_config config;]])],
275+
[AC_MSG_RESULT(yes)
276+
AC_DEFINE(FOUND_SSH,,found_ssh)],
277+
AC_MSG_RESULT(no)
278+
)
279+
265280
# we may want to come back later and add compile-time configuration for things
266281
# like datastructure providers, but for now it will all get compiled
267282

lib/bgpstream.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,13 +401,46 @@ void bgpstream_set_live_mode(bgpstream_t *bs) {
401401
bgpstream_debug("BS: set_blocking stop");
402402
}
403403

404+
#if defined(FOUND_RTR)
405+
/* Get the RTR-Socket & configuration
406+
*/
407+
struct rtr_mgr_config *bgpstream_get_rtr_config()
408+
{
409+
return cfg_tr;
410+
}
411+
412+
/* Set the RTR-Configuration
413+
*/
414+
int bgpstream_set_rtr_config(char *host, char *port, char *ssh_user,
415+
char *ssh_hostkey, char *ssh_privatekey,
416+
bool active)
417+
{
418+
rtr_server_conf.host = host;
419+
rtr_server_conf.port = port;
420+
rtr_server_conf.ssh_user = ssh_user;
421+
rtr_server_conf.ssh_hostkey = ssh_hostkey;
422+
rtr_server_conf.ssh_privatekey = ssh_privatekey;
423+
rtr_server_conf.active = active;
424+
425+
return 0;
426+
}
427+
#endif
404428

405429
/* turn on the bgpstream interface, i.e.:
406430
* it makes the interface ready
407431
* for a new get next call
432+
* it starts the RTR-Connection for validation if RTR is active
408433
*/
409434
int bgpstream_start(bgpstream_t *bs) {
410435
bgpstream_debug("BS: init start");
436+
#if defined(FOUND_RTR)
437+
if (rtr_server_conf.active) {
438+
cfg_tr = bgpstream_rtr_start_connection(
439+
rtr_server_conf.host, rtr_server_conf.port, NULL, NULL, NULL,
440+
rtr_server_conf.ssh_user, rtr_server_conf.ssh_hostkey,
441+
rtr_server_conf.ssh_privatekey);
442+
}
443+
#endif
411444
if(bs == NULL || (bs != NULL && bs->status != BGPSTREAM_STATUS_ALLOCATED)) {
412445
return 0; // nothing to init
413446
}
@@ -492,6 +525,12 @@ int bgpstream_get_next_record(bgpstream_t *bs,
492525
/* turn off the bgpstream interface */
493526
void bgpstream_stop(bgpstream_t *bs) {
494527
bgpstream_debug("BS: close start");
528+
#if defined(FOUND_RTR)
529+
if (rtr_server_conf.active) {
530+
bgpstream_rtr_close_connection(cfg_tr);
531+
rtr_server_conf.active = false;
532+
}
533+
#endif
495534
if(bs == NULL || (bs != NULL && bs->status != BGPSTREAM_STATUS_ON)) {
496535
return; // nothing to close
497536
}

lib/bgpstream.h

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

147147
} bgpstream_data_interface_option_t;
148148

149+
#if defined(FOUND_RTR)
150+
struct rtr_mgr_config *cfg_tr;
151+
152+
struct rtr_server_configure {
153+
char *host;
154+
char *port;
155+
char *ssh_user;
156+
char *ssh_hostkey;
157+
char *ssh_privatekey;
158+
bool active;
159+
} rtr_server_conf;
160+
149161
/** @} */
150162

151163
/**
152164
* @name Public API Functions
153165
*
154166
* @{ */
155167

168+
/** Get the configuration of the RTR-Socket-Manager
169+
*
170+
* @return a pointer to the configuration of the rtr-socket-manager
171+
*/
172+
struct rtr_mgr_config *bgpstream_get_rtr_config();
173+
174+
/** Set the configuration of the RTR-Socket-Manager
175+
*
176+
* @param host the host of the cache server
177+
* @param port the port of the cache server
178+
* @param active whether the rtr-validation is enabled
179+
*/
180+
int bgpstream_set_rtr_config(char *host, char *port, char *ssh_user,
181+
char *ssh_hostkey, char *ssh_privatekey,
182+
bool active);
183+
#endif
184+
156185
/** Create a new BGP Stream instance
157186
*
158187
* @return a pointer to a BGP Stream instance if successful, NULL otherwise

lib/bgpstream_elem.c

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,14 @@
3131
#include "bgpdump_lib.h"
3232
#include "utils.h"
3333

34+
#include "bgpstream.h"
3435
#include "bgpstream_utils.h"
3536

3637
#include "bgpstream_debug.h"
3738
#include "bgpstream_record.h"
3839

3940
#include "bgpstream_elem_int.h"
41+
#include "utils/bgpstream_utils_rtr.h"
4042

4143
/* ==================== PROTECTED FUNCTIONS ==================== */
4244

@@ -346,6 +348,15 @@ char *bgpstream_elem_custom_snprintf(char *buf, size_t len,
346348
if(B_FULL)
347349
return NULL;
348350

351+
#if defined(FOUND_RTR)
352+
/* RPKI Validation */
353+
char buf_rpki[1024];
354+
c = bgpstream_elem_get_rpki_validation_result_snprintf(
355+
buf_rpki, sizeof(buf_rpki), elem);
356+
strcat(buf, buf_rpki);
357+
written += c;
358+
buf_p += c;
359+
#endif
349360
/* END OF LINE */
350361
break;
351362

@@ -422,3 +433,104 @@ char *bgpstream_elem_snprintf(char *buf, size_t len,
422433
{
423434
return bgpstream_elem_custom_snprintf(buf, len, elem, 1);
424435
}
436+
437+
#if defined(FOUND_RTR)
438+
int bgpstream_elem_get_rpki_validation_result_snprintf(
439+
char *buf, size_t len, bgpstream_elem_t const *elem)
440+
{
441+
char result_output[1024] = "";
442+
if (elem->annotations.rpki_validation_status !=
443+
BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_NOTFOUND) {
444+
snprintf(result_output, sizeof(result_output), "%s%s", result_output,
445+
elem->annotations.rpki_validation_status ==
446+
BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_INVALID
447+
? "invalid;"
448+
: "valid;");
449+
for (int i = 0; i < elem->annotations.rpki_validation_result.asn_used;
450+
i++) {
451+
char asn[1024];
452+
snprintf(asn, sizeof(asn), "%" PRIu32 ",",
453+
elem->annotations.rpki_validation_result.asn_pfx[i].asn);
454+
strcat(result_output, asn);
455+
for (int j = 0;
456+
j < elem->annotations.rpki_validation_result.asn_pfx[i].pfx_used;
457+
j++) {
458+
char valid_prefix[INET6_ADDRSTRLEN];
459+
bgpstream_pfx_snprintf(valid_prefix, INET6_ADDRSTRLEN,
460+
(bgpstream_pfx_t *)&elem->annotations.rpki_validation_result
461+
.asn_pfx[i].pfxs[j].pfx);
462+
strcat(result_output, valid_prefix);
463+
snprintf(asn, sizeof(asn), "-%" PRIu8,
464+
elem->annotations.rpki_validation_result.asn_pfx[i]
465+
.pfxs[j].max_pfx_len);
466+
strcat(result_output, asn);
467+
strcat(result_output,
468+
j != elem->annotations.rpki_validation_result.asn_pfx[i]
469+
.pfx_used - 1
470+
? " "
471+
: "");
472+
}
473+
strcat(result_output,
474+
i != elem->annotations.rpki_validation_result.asn_used - 1 ? ";"
475+
: "");
476+
}
477+
} else {
478+
snprintf(result_output, sizeof(result_output), "%s%s", result_output,
479+
"notfound");
480+
}
481+
482+
return snprintf(buf, len, "%s", result_output);
483+
}
484+
485+
void bgpstream_elem_get_rpki_validation_result(bgpstream_elem_t *elem,
486+
char *prefix,
487+
uint32_t origin_asn,
488+
uint8_t mask_len)
489+
{
490+
if (elem->annotations.rpki_validation_status ==
491+
BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_NOTVALIDATED) {
492+
cfg_tr = bgpstream_get_rtr_config();
493+
494+
struct reasoned_result res_reasoned =
495+
bgpstream_rtr_validate_reason(cfg_tr, origin_asn, prefix, mask_len);
496+
497+
if (res_reasoned.result == BGP_PFXV_STATE_VALID) {
498+
elem->annotations.rpki_validation_status =
499+
BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_VALID;
500+
}
501+
if (res_reasoned.result == BGP_PFXV_STATE_NOT_FOUND) {
502+
elem->annotations.rpki_validation_status =
503+
BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_NOTFOUND;
504+
}
505+
if (res_reasoned.result == BGP_PFXV_STATE_INVALID) {
506+
elem->annotations.rpki_validation_status =
507+
BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_INVALID;
508+
}
509+
510+
if (elem->annotations.rpki_validation_status !=
511+
BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_NOTFOUND) {
512+
bgpstream_rpki_validation_result_init(
513+
&elem->annotations.rpki_validation_result, 2);
514+
char valid_prefix[INET6_ADDRSTRLEN];
515+
char reason_prefix[INET6_ADDRSTRLEN];
516+
517+
for (int i = 0; i < res_reasoned.reason_len; i++) {
518+
bgpstream_rpki_validation_result_insert_asn(
519+
&elem->annotations.rpki_validation_result,
520+
res_reasoned.reason[i].asn);
521+
lrtr_ip_addr_to_str(&(res_reasoned.reason[i].prefix), reason_prefix,
522+
sizeof(reason_prefix));
523+
snprintf(valid_prefix, sizeof(valid_prefix), "%s/%" PRIu8, reason_prefix,
524+
res_reasoned.reason[i].min_len);
525+
526+
bgpstream_pfx_t pfx;
527+
bgpstream_str2pfx(valid_prefix, (bgpstream_pfx_storage_t *)&pfx);
528+
bgpstream_rpki_validation_result_insert_pfx(
529+
&elem->annotations.rpki_validation_result,
530+
res_reasoned.reason[i].asn, &pfx, res_reasoned.reason[i].max_len);
531+
}
532+
}
533+
free(res_reasoned.reason);
534+
}
535+
}
536+
#endif

lib/bgpstream_elem.h

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#define __BGPSTREAM_ELEM_H
2626

2727
#include "bgpstream_utils.h"
28+
#include "bgpstream_utils_as_path.h"
2829

2930
/** @file
3031
*
@@ -105,13 +106,47 @@ typedef enum {
105106

106107
} bgpstream_elem_type_t;
107108

109+
/** Validation types */
110+
typedef enum {
111+
112+
/** Valid */
113+
BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_VALID = 1,
114+
115+
/** Invalid */
116+
BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_INVALID = 0,
117+
118+
/** Not found */
119+
BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_NOTFOUND = -1,
120+
121+
/** Not validated */
122+
BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_NOTVALIDATED = 2,
123+
124+
} bgpstream_validation_status_type_t;
125+
108126
/** @} */
109127

110128
/**
111129
* @name Public Data Structures
112130
*
113131
* @{ */
114132

133+
/** A BGP Stream Elem object for Annotations */
134+
typedef struct struct_bgpstream_elem_annotations_t {
135+
136+
/** RPKI validation status
137+
*
138+
* RPKI validation status for a given prefix
139+
*/
140+
bgpstream_validation_status_type_t rpki_validation_status;
141+
142+
/** RPKI validation result
143+
*
144+
* RPKI validation result (all valid ASNs) for a given prefix
145+
*/
146+
bgpstream_rpki_validation_result_t rpki_validation_result;
147+
148+
} bgpstream_elem_annotations_t;
149+
115150
/** A BGP Stream Elem object */
116151
typedef struct struct_bgpstream_elem_t {
117152

@@ -165,6 +200,12 @@ typedef struct struct_bgpstream_elem_t {
165200
*/
166201
bgpstream_elem_peerstate_t new_state;
167202

203+
/** Annotations
204+
*
205+
* All additional annotations
206+
*/
207+
bgpstream_elem_annotations_t annotations;
208+
168209
} bgpstream_elem_t;
169210

170211
/** @} */
@@ -238,6 +279,24 @@ int bgpstream_elem_peerstate_snprintf(char *buf, size_t len,
238279
char *bgpstream_elem_snprintf(char *buf, size_t len,
239280
const bgpstream_elem_t *elem);
240281

282+
#if defined(FOUND_RTR)
283+
/** Write the string representation of the RPKI validation result of an elem
284+
*
285+
* @param elem the elem whose RPKI validation result will be printed
286+
*/
287+
int bgpstream_elem_get_rpki_validation_result_snprintf(
288+
char *buf, size_t len, bgpstream_elem_t const *elem);
289+
290+
/** Get the result of the RPKI-Validation for the elem
291+
*
292+
* @param elem the elem which will be validated
293+
*/
294+
void bgpstream_elem_get_rpki_validation_result(bgpstream_elem_t *elem,
295+
char *prefix,
296+
uint32_t origin_asn,
297+
uint8_t mask_len);
298+
#endif
299+
241300
/** @} */
242301

243302
#endif /* __BGPSTREAM_ELEM_H */

0 commit comments

Comments
 (0)