Skip to content
Permalink
Browse files

Merge pull request #2677 from rtrlib/2018-07-18-master-bugfix

bgpd: rpki bugfixes
  • Loading branch information...
qlyoung committed Aug 23, 2018
2 parents 753e2c9 + 31a2af3 commit 82b410b0453f2269c5b469203db0f61b6541bcff
Showing with 87 additions and 38 deletions.
  1. +87 −38 bgpd/bgp_rpki.c
@@ -47,6 +47,7 @@
#include "bgpd/bgp_attr.h" #include "bgpd/bgp_attr.h"
#include "bgpd/bgp_aspath.h" #include "bgpd/bgp_aspath.h"
#include "bgpd/bgp_route.h" #include "bgpd/bgp_route.h"
#include "lib/network.h"
#include "lib/thread.h" #include "lib/thread.h"
#include "rtrlib/rtrlib.h" #include "rtrlib/rtrlib.h"
#include "rtrlib/rtr_mgr.h" #include "rtrlib/rtr_mgr.h"
@@ -131,12 +132,14 @@ static route_map_result_t route_match(void *rule, const struct prefix *prefix,
static void *route_match_compile(const char *arg); static void *route_match_compile(const char *arg);
static void revalidate_bgp_node(struct bgp_node *bgp_node, afi_t afi, static void revalidate_bgp_node(struct bgp_node *bgp_node, afi_t afi,
safi_t safi); safi_t safi);
static void revalidate_all_routes(void);


static struct rtr_mgr_config *rtr_config; static struct rtr_mgr_config *rtr_config;
static struct list *cache_list; static struct list *cache_list;
static int rtr_is_running; static int rtr_is_running;
static int rtr_is_stopping; static int rtr_is_stopping;
static int rtr_is_starting; static int rtr_is_starting;
static _Atomic int rtr_update_overflow;
static int rpki_debug; static int rpki_debug;
static unsigned int polling_period; static unsigned int polling_period;
static unsigned int expire_interval; static unsigned int expire_interval;
@@ -229,7 +232,7 @@ static void *route_match_compile(const char *arg)
{ {
int *rpki_status; int *rpki_status;


rpki_status = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(uint8_t)); rpki_status = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(int));


if (strcmp(arg, "valid") == 0) if (strcmp(arg, "valid") == 0)
*rpki_status = RPKI_VALID; *rpki_status = RPKI_VALID;
@@ -345,6 +348,19 @@ static int bgpd_sync_callback(struct thread *thread)


thread_add_read(bm->master, bgpd_sync_callback, NULL, thread_add_read(bm->master, bgpd_sync_callback, NULL,
rpki_sync_socket_bgpd, NULL); rpki_sync_socket_bgpd, NULL);

if (atomic_load_explicit(&rtr_update_overflow, memory_order_seq_cst)) {
while (read(rpki_sync_socket_bgpd, &rec,
sizeof(struct pfx_record))
!= -1)
;

atomic_store_explicit(&rtr_update_overflow, 0,
memory_order_seq_cst);
revalidate_all_routes();
return 0;
}

int retval = int retval =
read(rpki_sync_socket_bgpd, &rec, sizeof(struct pfx_record)); read(rpki_sync_socket_bgpd, &rec, sizeof(struct pfx_record));
if (retval != sizeof(struct pfx_record)) { if (retval != sizeof(struct pfx_record)) {
@@ -356,26 +372,36 @@ static int bgpd_sync_callback(struct thread *thread)
afi_t afi = (rec.prefix.ver == LRTR_IPV4) ? AFI_IP : AFI_IP6; afi_t afi = (rec.prefix.ver == LRTR_IPV4) ? AFI_IP : AFI_IP6;


for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp)) { for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp)) {
safi_t safi; struct peer *peer;
struct listnode *peer_listnode;

for (ALL_LIST_ELEMENTS_RO(bgp->peer, peer_listnode, peer)) {
safi_t safi;


for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) { for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
if (!bgp->rib[afi][safi]) if (!peer->bgp->rib[afi][safi])
continue; continue;


struct list *matches = list_new(); struct list *matches = list_new();


matches->del = (void (*)(void *))bgp_unlock_node; matches->del =
(void (*)(void *))bgp_unlock_node;


bgp_table_range_lookup(bgp->rib[afi][safi], prefix, bgp_table_range_lookup(
rec.max_len, matches); peer->bgp->rib[afi][safi], prefix,
rec.max_len, matches);




struct bgp_node *bgp_node; struct bgp_node *bgp_node;
struct listnode *bgp_listnode;


for (ALL_LIST_ELEMENTS_RO(matches, node, bgp_node)) for (ALL_LIST_ELEMENTS_RO(matches, bgp_listnode,
revalidate_bgp_node(bgp_node, afi, safi); bgp_node))
revalidate_bgp_node(bgp_node, afi,
safi);


list_delete_and_null(&matches); list_delete_and_null(&matches);
}
} }
} }


@@ -398,40 +424,37 @@ static void revalidate_bgp_node(struct bgp_node *bgp_node, afi_t afi,
label = bgp_info->extra->label; label = bgp_info->extra->label;
num_labels = bgp_info->extra->num_labels; num_labels = bgp_info->extra->num_labels;
} }
ret = bgp_update(ain->peer, &bgp_node->p, 0, ain->attr, afi, ret = bgp_update(ain->peer, &bgp_node->p, ain->addpath_rx_id,
safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, ain->attr, afi, safi, ZEBRA_ROUTE_BGP,
label, num_labels, 1, NULL); BGP_ROUTE_NORMAL, NULL, label, num_labels, 1,
NULL);


if (ret < 0) { if (ret < 0)
bgp_unlock_node(bgp_node);
return; return;
}
} }
} }


static void revalidate_all_routes(void) static void revalidate_all_routes(void)
{ {
struct bgp *bgp; struct bgp *bgp;
struct listnode *node; struct listnode *node;
struct bgp_node *bgp_node;


for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp)) { for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp)) {
for (size_t i = 0; i < 2; i++) { struct peer *peer;
safi_t safi; struct listnode *peer_listnode;
afi_t afi = (i == 0) ? AFI_IP : AFI_IP6;


for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) { for (ALL_LIST_ELEMENTS_RO(bgp->peer, peer_listnode, peer)) {
if (!bgp->rib[afi][safi])
continue; for (size_t i = 0; i < 2; i++) {
safi_t safi;
afi_t afi = (i == 0) ? AFI_IP : AFI_IP6;


for (bgp_node = for (safi = SAFI_UNICAST; safi < SAFI_MAX;
bgp_table_top(bgp->rib[afi][safi]); safi++) {
bgp_node; if (!peer->bgp->rib[afi][safi])
bgp_node = bgp_route_next(bgp_node)) { continue;
if (bgp_node->info != NULL) {
revalidate_bgp_node(bgp_node, bgp_soft_reconfig_in(peer, afi, safi);
afi, safi);
}
} }
} }
} }
@@ -442,28 +465,53 @@ static void rpki_update_cb_sync_rtr(struct pfx_table *p __attribute__((unused)),
const struct pfx_record rec, const struct pfx_record rec,
const bool added __attribute__((unused))) const bool added __attribute__((unused)))
{ {
if (rtr_is_stopping || rtr_is_starting) if (rtr_is_stopping || rtr_is_starting
|| atomic_load_explicit(&rtr_update_overflow, memory_order_seq_cst))
return; return;


int retval = int retval =
write(rpki_sync_socket_rtr, &rec, sizeof(struct pfx_record)); write(rpki_sync_socket_rtr, &rec, sizeof(struct pfx_record));
if (retval != sizeof(struct pfx_record)) if (retval == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))
atomic_store_explicit(&rtr_update_overflow, 1,
memory_order_seq_cst);

else if (retval != sizeof(struct pfx_record))
RPKI_DEBUG("Could not write to rpki_sync_socket_rtr"); RPKI_DEBUG("Could not write to rpki_sync_socket_rtr");
} }


static void rpki_init_sync_socket(void) static void rpki_init_sync_socket(void)
{ {
int fds[2]; int fds[2];
const char *msg;


RPKI_DEBUG("initializing sync socket"); RPKI_DEBUG("initializing sync socket");
if (socketpair(PF_LOCAL, SOCK_DGRAM, 0, fds) != 0) { if (socketpair(PF_LOCAL, SOCK_DGRAM, 0, fds) != 0) {
RPKI_DEBUG("Could not open rpki sync socket"); msg = "could not open rpki sync socketpair";
return; goto err;
} }
rpki_sync_socket_rtr = fds[0]; rpki_sync_socket_rtr = fds[0];
rpki_sync_socket_bgpd = fds[1]; rpki_sync_socket_bgpd = fds[1];

if (set_nonblocking(rpki_sync_socket_rtr) != 0) {
msg = "could not set rpki_sync_socket_rtr to non blocking";
goto err;
}

if (set_nonblocking(rpki_sync_socket_bgpd) != 0) {
msg = "could not set rpki_sync_socket_bgpd to non blocking";
goto err;
}


thread_add_read(bm->master, bgpd_sync_callback, NULL, thread_add_read(bm->master, bgpd_sync_callback, NULL,
rpki_sync_socket_bgpd, NULL); rpki_sync_socket_bgpd, NULL);

return;

err:
zlog_err("RPKI: %s", msg);
abort();

} }


static int bgp_rpki_init(struct thread_master *master) static int bgp_rpki_init(struct thread_master *master)
@@ -514,6 +562,7 @@ static int start(void)


rtr_is_stopping = 0; rtr_is_stopping = 0;
rtr_is_starting = 1; rtr_is_starting = 1;
rtr_update_overflow = 0;


if (list_isempty(cache_list)) { if (list_isempty(cache_list)) {
RPKI_DEBUG( RPKI_DEBUG(

0 comments on commit 82b410b

Please sign in to comment.
You can’t perform that action at this time.