Skip to content

Commit 88c1ba2

Browse files
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 and /pull/26 (update)
1 parent d9ad3cc commit 88c1ba2

16 files changed

+434
-556
lines changed

configure.ac

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,20 +262,42 @@ AC_DEFINE_UNQUOTED([ED_PLUGIN_INIT_ALL_ENABLED], $ED_PLUGIN_INIT_ALL_ENABLED,
262262

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

265+
# RTR configuration
265266
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
266274
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include "rtrlib/rtrlib.h"]])],
267275
[AC_MSG_RESULT(yes)
268-
AC_DEFINE(FOUND_RTR,,found_rtr)],
276+
AC_DEFINE([WITH_RTR],[1],[Building with RTR support])],
269277
AC_MSG_RESULT(no)
270278
)
279+
else
280+
AC_MSG_RESULT([no])
281+
fi
271282

283+
# SSH configuration
272284
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
273292
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include "rtrlib/rtrlib.h"]],
274293
[[struct tr_ssh_config config;]])],
275294
[AC_MSG_RESULT(yes)
276-
AC_DEFINE(FOUND_SSH,,found_ssh)],
295+
AC_DEFINE([WITH_SSH],[1],[Building with SSH support])],
277296
AC_MSG_RESULT(no)
278297
)
298+
else
299+
AC_MSG_RESULT([no])
300+
fi
279301

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

lib/bgpstream.c

Lines changed: 26 additions & 21 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,27 +406,27 @@ void bgpstream_set_live_mode(bgpstream_t *bs) {
401406
bgpstream_debug("BS: set_blocking stop");
402407
}
403408

404-
#if defined(FOUND_RTR)
409+
#ifdef WITH_RTR
405410
/* Get the RTR-Socket & configuration
406411
*/
407-
struct rtr_mgr_config *bgpstream_get_rtr_config()
412+
struct rtr_mgr_config *bgpstream_get_rtr_config(bgpstream_t *bs)
408413
{
409-
return cfg_tr;
414+
return bs->cfg_tr;
410415
}
411416

412417
/* Set the RTR-Configuration
413418
*/
414-
int bgpstream_set_rtr_config(char *host, char *port, char *ssh_user,
419+
int bgpstream_set_rtr_config(bgpstream_t *bs, char *host, char *port, char *ssh_user,
415420
char *ssh_hostkey, char *ssh_privatekey,
416-
bool active)
421+
int active)
417422
{
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;
424423

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;
425430
return 0;
426431
}
427432
#endif
@@ -433,12 +438,12 @@ int bgpstream_set_rtr_config(char *host, char *port, char *ssh_user,
433438
*/
434439
int bgpstream_start(bgpstream_t *bs) {
435440
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);
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);
442447
}
443448
#endif
444449
if(bs == NULL || (bs != NULL && bs->status != BGPSTREAM_STATUS_ALLOCATED)) {
@@ -525,10 +530,10 @@ int bgpstream_get_next_record(bgpstream_t *bs,
525530
/* turn off the bgpstream interface */
526531
void bgpstream_stop(bgpstream_t *bs) {
527532
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;
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;
532537
}
533538
#endif
534539
if(bs == NULL || (bs != NULL && bs->status != BGPSTREAM_STATUS_ON)) {

lib/bgpstream.h

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -146,17 +146,7 @@ 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;
149+
#ifdef WITH_RTR
160150

161151
/** @} */
162152

@@ -173,13 +163,18 @@ struct rtr_mgr_config *bgpstream_get_rtr_config();
173163

174164
/** Set the configuration of the RTR-Socket-Manager
175165
*
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
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
179173
*/
180-
int bgpstream_set_rtr_config(char *host, char *port, char *ssh_user,
174+
int bgpstream_set_rtr_config(bgpstream_t *bs,
175+
char *host, char *port, char *ssh_user,
181176
char *ssh_hostkey, char *ssh_privatekey,
182-
bool active);
177+
int active);
183178
#endif
184179

185180
/** Create a new BGP Stream instance

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: 71 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,17 @@
3030

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

3435
#include "bgpstream.h"
3536
#include "bgpstream_utils.h"
3637

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

41+
#include "bgpstream_constants.h"
4042
#include "bgpstream_elem_int.h"
41-
#include "utils/bgpstream_utils_rtr.h"
43+
#include "bgpstream_utils_rtr.h"
4244

4345
/* ==================== PROTECTED FUNCTIONS ==================== */
4446

@@ -83,12 +85,25 @@ void bgpstream_elem_destroy(bgpstream_elem_t *elem) {
8385
bgpstream_community_set_destroy(elem->communities);
8486
elem->communities = NULL;
8587

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+
8695
free(elem);
8796
}
8897

8998
void bgpstream_elem_clear(bgpstream_elem_t *elem) {
9099
bgpstream_as_path_clear(elem->aspath);
91100
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
92107
}
93108

94109
bgpstream_elem_t *bgpstream_elem_copy(bgpstream_elem_t *dst,
@@ -348,14 +363,16 @@ char *bgpstream_elem_custom_snprintf(char *buf, size_t len,
348363
if(B_FULL)
349364
return NULL;
350365

351-
#if defined(FOUND_RTR)
366+
#ifdef WITH_RTR
352367
/* 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;
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+
}
359376
#endif
360377
/* END OF LINE */
361378
break;
@@ -434,46 +451,26 @@ char *bgpstream_elem_snprintf(char *buf, size_t len,
434451
return bgpstream_elem_custom_snprintf(buf, len, elem, 1);
435452
}
436453

437-
#if defined(FOUND_RTR)
454+
#ifdef WITH_RTR
438455
int bgpstream_elem_get_rpki_validation_result_snprintf(
439456
char *buf, size_t len, bgpstream_elem_t const *elem)
440457
{
441-
char result_output[1024] = "";
458+
int key;
459+
char *val;
460+
char result_output[BGPSTREAM_RPKI_RST_MAX_LEN];
461+
char valid_prefixes[BGPSTREAM_RPKI_RST_MAX_LEN];
442462
if (elem->annotations.rpki_validation_status !=
443463
BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_NOTFOUND) {
444464
snprintf(result_output, sizeof(result_output), "%s%s", result_output,
445465
elem->annotations.rpki_validation_status ==
446466
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-
}
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;
477474
} else {
478475
snprintf(result_output, sizeof(result_output), "%s%s", result_output,
479476
"notfound");
@@ -482,17 +479,16 @@ int bgpstream_elem_get_rpki_validation_result_snprintf(
482479
return snprintf(buf, len, "%s", result_output);
483480
}
484481

485-
void bgpstream_elem_get_rpki_validation_result(bgpstream_elem_t *elem,
482+
void bgpstream_elem_get_rpki_validation_result(struct rtr_mgr_config *cfg, bgpstream_elem_t *elem,
486483
char *prefix,
487484
uint32_t origin_asn,
488485
uint8_t mask_len)
489486
{
490487
if (elem->annotations.rpki_validation_status ==
491488
BGPSTREAM_ELEM_RPKI_VALIDATION_STATUS_NOTVALIDATED) {
492-
cfg_tr = bgpstream_get_rtr_config();
493489

494490
struct reasoned_result res_reasoned =
495-
bgpstream_rtr_validate_reason(cfg_tr, origin_asn, prefix, mask_len);
491+
bgpstream_rtr_validate_reason(cfg, origin_asn, prefix, mask_len);
496492

497493
if (res_reasoned.result == BGP_PFXV_STATE_VALID) {
498494
elem->annotations.rpki_validation_status =
@@ -509,27 +505,43 @@ void bgpstream_elem_get_rpki_validation_result(bgpstream_elem_t *elem,
509505

510506
if (elem->annotations.rpki_validation_status !=
511507
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];
508+
515509
char reason_prefix[INET6_ADDRSTRLEN];
510+
char buf_p[BGPSTREAM_RPKI_RST_MAX_LEN];
511+
512+
int ret;
513+
khiter_t k;
516514

515+
if(elem->annotations.khash_init != 1) {
516+
elem->annotations.rpki_kh = kh_init(rpki_result);
517+
elem->annotations.khash_init = 1;
518+
}
519+
517520
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);
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+
}
531542
}
532543
}
544+
533545
free(res_reasoned.reason);
534546
}
535547
}

0 commit comments

Comments
 (0)