mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2025-01-03 15:41:54 +00:00
Early integration of RTRlib into BIRD RPKI proto
lib/lists: add get_list_length(list *) function
This commit is contained in:
parent
2c66ced11a
commit
149220738b
16
lib/lists.c
16
lib/lists.c
@ -175,3 +175,19 @@ add_tail_list(list *to, list *l)
|
|||||||
q->next = (node *) &to->null;
|
q->next = (node *) &to->null;
|
||||||
to->tail = q;
|
to->tail = q;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get_list_size - get count of items in list
|
||||||
|
* @l: list
|
||||||
|
*/
|
||||||
|
LIST_INLINE uint
|
||||||
|
get_list_length(list *l)
|
||||||
|
{
|
||||||
|
unsigned int size = 0;
|
||||||
|
node *n;
|
||||||
|
WALK_LIST(n, *l)
|
||||||
|
{
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
@ -65,6 +65,7 @@ void rem2_node(node *);
|
|||||||
void add_tail_list(list *, list *);
|
void add_tail_list(list *, list *);
|
||||||
void init_list(list *);
|
void init_list(list *);
|
||||||
void insert_node(node *, node *);
|
void insert_node(node *, node *);
|
||||||
|
uint get_list_length(list *);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -14,25 +14,24 @@ CF_DEFINES
|
|||||||
|
|
||||||
#define RPKI_CFG ((struct rpki_config *) this_proto)
|
#define RPKI_CFG ((struct rpki_config *) this_proto)
|
||||||
|
|
||||||
|
static struct rpki_cache *this_rpki_cache;
|
||||||
|
|
||||||
CF_DECLS
|
CF_DECLS
|
||||||
|
|
||||||
CF_KEYWORDS(RPKI, CACHE, SERVER, SERVERS)
|
CF_KEYWORDS(RPKI, CACHE, LIST, PREFERENCE)
|
||||||
|
|
||||||
CF_GRAMMAR
|
CF_GRAMMAR
|
||||||
|
|
||||||
CF_ADDTO(proto, rpki_proto)
|
CF_ADDTO(proto, rpki_proto)
|
||||||
|
|
||||||
rpki_proto_start: proto_start RPKI {
|
rpki_proto:
|
||||||
this_proto = proto_config_new(&proto_rpki, $1);
|
rpki_proto_start proto_name '{' rpki_proto_opts '}'
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
rpki_proto_item:
|
rpki_proto_start:
|
||||||
proto_item
|
proto_start RPKI {
|
||||||
| CACHE SERVER ipa expr {
|
this_proto = proto_config_new(&proto_rpki, $1);
|
||||||
RPKI_CFG->remote.ip = $3;
|
init_list(&RPKI_CFG->cache_list);
|
||||||
RPKI_CFG->remote.port = $4;
|
}
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
rpki_proto_opts:
|
rpki_proto_opts:
|
||||||
@ -40,8 +39,40 @@ rpki_proto_opts:
|
|||||||
| rpki_proto_opts rpki_proto_item ';'
|
| rpki_proto_opts rpki_proto_item ';'
|
||||||
;
|
;
|
||||||
|
|
||||||
rpki_proto:
|
rpki_proto_item:
|
||||||
rpki_proto_start proto_name '{' rpki_proto_opts '}'
|
proto_item
|
||||||
|
| CACHE LIST '{' rpki_cache_list '}'
|
||||||
|
;
|
||||||
|
|
||||||
|
rpki_cache_list:
|
||||||
|
rpki_cache_list_item
|
||||||
|
| rpki_cache_list ',' rpki_cache_list_item
|
||||||
|
;
|
||||||
|
|
||||||
|
rpki_cache_list_item:
|
||||||
|
rpki_cache_init text rpki_cache_opts {
|
||||||
|
this_rpki_cache->full_domain_name = $2;
|
||||||
|
add_tail(&RPKI_CFG->cache_list, &this_rpki_cache->n);
|
||||||
|
}
|
||||||
|
| rpki_cache_init ipa rpki_cache_opts {
|
||||||
|
this_rpki_cache->ip = $2;
|
||||||
|
add_tail(&RPKI_CFG->cache_list, &this_rpki_cache->n);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
rpki_cache_init:
|
||||||
|
/* empty */ { this_rpki_cache = rpki_new_cache(); }
|
||||||
|
;
|
||||||
|
|
||||||
|
rpki_cache_opts:
|
||||||
|
/* empty */
|
||||||
|
| rpki_cache_opts rpki_cache_opts_item ';'
|
||||||
|
;
|
||||||
|
|
||||||
|
rpki_cache_opts_item:
|
||||||
|
PORT expr { bsnprintf(this_rpki_cache->port, RPKI_PORT_MAX_LENGTH_STR, "%u", (u16) $2); }
|
||||||
|
| PREFERENCE expr { this_rpki_cache->preference = $2; }
|
||||||
|
;
|
||||||
|
|
||||||
CF_CODE
|
CF_CODE
|
||||||
|
|
||||||
|
@ -12,36 +12,149 @@
|
|||||||
|
|
||||||
#define LOCAL_DEBUG
|
#define LOCAL_DEBUG
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "proto/rpki/rpki.h"
|
#include "proto/rpki/rpki.h"
|
||||||
|
#include "lib/socket.h"
|
||||||
|
|
||||||
|
struct proto *ugly_hack_to_get_proto;
|
||||||
|
|
||||||
|
static void status_cb(const struct rtr_mgr_group *group, enum rtr_mgr_status status, const struct rtr_socket *socket, void *data)
|
||||||
|
{
|
||||||
|
struct rpki_proto *rpki = data;
|
||||||
|
if(status == RTR_MGR_ERROR)
|
||||||
|
{
|
||||||
|
RPKI_TRACE(rpki, "Error -> Should we here stop the protocol?"); /* FIXME */
|
||||||
|
}
|
||||||
|
|
||||||
|
RPKI_TRACE(rpki, "Status: %s\t%s", rtr_mgr_status_to_str(status), rtr_state_to_str(socket->state));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void update_cb(struct pfx_table *p, const struct pfx_record rec, const bool added)
|
||||||
|
{
|
||||||
|
/* FIXME: update_cb() should have void *data attribute, same like status_cb() */
|
||||||
|
struct proto *P = ugly_hack_to_get_proto;
|
||||||
|
struct rpki_proto *rpki = (struct rpki_proto *) P;
|
||||||
|
|
||||||
|
ip4_addr ip4 = {};
|
||||||
|
ip6_addr ip6 = {};
|
||||||
|
char ip[INET6_ADDRSTRLEN];
|
||||||
|
if (rec.prefix.ver == RTRLIB_IPV4)
|
||||||
|
{
|
||||||
|
ip4 = ipa_from_u32(rec.prefix.u.addr4.addr);
|
||||||
|
ip4_ntop(ip4, ip);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ip6 = ip6_build(rec.prefix.u.addr6.addr[0], rec.prefix.u.addr6.addr[1], rec.prefix.u.addr6.addr[2], rec.prefix.u.addr6.addr[3]);
|
||||||
|
ip6_ntop(ip6, ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(added)
|
||||||
|
{
|
||||||
|
RPKI_TRACE(rpki, "+++ %45s/%u-%-3u \tASN: %10u", ip, rec.min_len, rec.max_len, rec.asn);
|
||||||
|
// P->rte_insert();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RPKI_TRACE(rpki, "--- %45s/%u-%-3u \tASN: %10u", ip, rec.min_len, rec.max_len, rec.asn);
|
||||||
|
// P->rte_remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static struct proto *
|
static struct proto *
|
||||||
rpki_init(struct proto_config *c)
|
rpki_init(struct proto_config *C)
|
||||||
{
|
{
|
||||||
struct proto *p = proto_new(c, sizeof(struct rpki_proto));
|
struct proto *P = proto_new(C, sizeof(struct rpki_proto));
|
||||||
|
struct rpki_proto *rpki = (struct rpki_proto *) P;
|
||||||
|
struct rpki_config *cf = (struct rpki_config *) C;
|
||||||
|
|
||||||
log(L_DEBUG "------------- rpki_init -------------");
|
RPKI_TRACE(rpki, "------------- rpki_init -------------");
|
||||||
|
|
||||||
|
ugly_hack_to_get_proto = P;
|
||||||
|
|
||||||
/* TODO: Add defaults */
|
/* TODO: Add defaults */
|
||||||
return p;
|
return P;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct rpki_cache *
|
||||||
|
rpki_new_cache(void)
|
||||||
|
{
|
||||||
|
struct rpki_cache *cache = (struct rpki_cache *)cfg_allocz(sizeof(struct rpki_cache));
|
||||||
|
strcpy(cache->port, RPKI_PORT);
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
normalize_fulfillment_of_cache(struct rpki_cache *cache)
|
||||||
|
{
|
||||||
|
if (cache->full_domain_name == NULL)
|
||||||
|
{
|
||||||
|
bsnprintf(cache->ip_buf, INET6_ADDRSTRLEN, "%I", cache->ip);
|
||||||
|
cache->full_domain_name = cache->ip_buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
bzero(&cache->rtr_tcp, sizeof(struct rtr_socket));
|
||||||
|
bzero(&cache->tcp_config, sizeof(struct tr_tcp_config));
|
||||||
|
bzero(&cache->tr_tcp, sizeof(struct tr_socket));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
rpki_start(struct proto *p)
|
rpki_start(struct proto *P)
|
||||||
{
|
{
|
||||||
struct proto_rpki *rpki = (struct proto_rpki *) p;
|
struct rpki_proto *rpki = (struct rpki_proto *) P;
|
||||||
struct rpki_config *cf = (struct rpki_config *) (p->cf);
|
struct rpki_config *cf = (struct rpki_config *) (P->cf);
|
||||||
|
|
||||||
log(L_DEBUG "------------- rpki_start -------------");
|
RPKI_TRACE(rpki, "------------- rpki_start -------------");
|
||||||
|
|
||||||
|
rpki->rtr_groups_len = get_list_length(&cf->cache_list);
|
||||||
|
rpki->rtr_groups = mb_allocz(P->pool, rpki->rtr_groups_len * sizeof(struct rtr_mgr_group));
|
||||||
|
struct rtr_mgr_group *groups = rpki->rtr_groups;
|
||||||
|
|
||||||
|
uint idx = 0;
|
||||||
|
struct rpki_cache *cache;
|
||||||
|
WALK_LIST(cache, cf->cache_list)
|
||||||
|
{
|
||||||
|
struct tr_tcp_config *tcp_config = &cache->tcp_config;
|
||||||
|
struct rtr_socket *rtr_tcp = &cache->rtr_tcp;
|
||||||
|
struct tr_socket *tr_tcp = &cache->tr_tcp;
|
||||||
|
|
||||||
|
normalize_fulfillment_of_cache(cache);
|
||||||
|
|
||||||
|
tcp_config->host = cache->full_domain_name;
|
||||||
|
tcp_config->port = cache->port;
|
||||||
|
tr_tcp_init(tcp_config, tr_tcp);
|
||||||
|
|
||||||
|
// create an rtr_socket and associate it with the transport socket
|
||||||
|
rtr_tcp->tr_socket = tr_tcp;
|
||||||
|
|
||||||
|
groups[idx].sockets = mb_allocz(P->pool, 1 * sizeof(struct rtr_socket *));
|
||||||
|
groups[idx].sockets_len = 1;
|
||||||
|
groups[idx].sockets[0] = rtr_tcp;
|
||||||
|
groups[idx].preference = cache->preference;
|
||||||
|
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
rpki->rtr_conf = rtr_mgr_init(groups, rpki->rtr_groups_len, 30, 520, &update_cb, NULL, &status_cb, rpki);
|
||||||
|
rtr_mgr_start(rpki->rtr_conf);
|
||||||
|
|
||||||
return PS_UP;
|
return PS_UP;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
rpki_shutdown(struct proto *p)
|
rpki_shutdown(struct proto *P)
|
||||||
{
|
{
|
||||||
struct proto_rpki *rp = (struct proto_rpki *) p;
|
struct rpki_proto *rpki = (struct rpki_proto *) P;
|
||||||
|
struct rpki_config *cf = (struct rpki_config *) (P->cf);
|
||||||
|
|
||||||
log(L_DEBUG "------------- rpki_shutdown -------------");
|
RPKI_TRACE(rpki, "------------- rpki_shutdown -------------");
|
||||||
|
|
||||||
|
rtr_mgr_stop(rpki->rtr_conf);
|
||||||
|
rtr_mgr_free(rpki->rtr_conf);
|
||||||
|
|
||||||
|
/* TODO: fix memory leaks created by start->disable->enable rpki protocol */
|
||||||
|
|
||||||
return PS_DOWN;
|
return PS_DOWN;
|
||||||
}
|
}
|
||||||
@ -49,7 +162,7 @@ rpki_shutdown(struct proto *p)
|
|||||||
static int
|
static int
|
||||||
rpki_reconfigure(struct proto *p, struct proto_config *c)
|
rpki_reconfigure(struct proto *p, struct proto_config *c)
|
||||||
{
|
{
|
||||||
struct proto_rpki *rpki = (struct proto_rpki *) p;
|
struct rpki_proto *rpki = (struct rpki_proto *) p;
|
||||||
struct rpki_config *new = (struct rpki_config *) c;
|
struct rpki_config *new = (struct rpki_config *) c;
|
||||||
|
|
||||||
log(L_DEBUG "------------- rpki_reconfigure -------------");
|
log(L_DEBUG "------------- rpki_reconfigure -------------");
|
||||||
|
@ -9,22 +9,47 @@
|
|||||||
#ifndef _BIRD_RPKI_H_
|
#ifndef _BIRD_RPKI_H_
|
||||||
#define _BIRD_RPKI_H_
|
#define _BIRD_RPKI_H_
|
||||||
|
|
||||||
|
#include "rtrlib/rtrlib.h"
|
||||||
|
|
||||||
#include "nest/bird.h"
|
#include "nest/bird.h"
|
||||||
#include "nest/protocol.h"
|
#include "nest/protocol.h"
|
||||||
|
|
||||||
struct cache_server {
|
#define RPKI_PORT "8282"
|
||||||
|
#define RPKI_PORT_MAX_LENGTH_STR 6
|
||||||
|
|
||||||
|
#define RPKI_TRACE(rpki, msg, args...) \
|
||||||
|
do { \
|
||||||
|
if (rpki->p.debug) \
|
||||||
|
log(L_TRACE "%s: " msg, rpki->p.name , ## args ); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
struct rpki_cache {
|
||||||
|
node n; /* in struct rpki_config.cache_list */
|
||||||
ip_addr ip;
|
ip_addr ip;
|
||||||
u16 port;
|
char *full_domain_name;
|
||||||
|
char port[RPKI_PORT_MAX_LENGTH_STR]; /* the highest port is "65535" */
|
||||||
|
u8 preference;
|
||||||
|
|
||||||
|
/* below are private variables */
|
||||||
|
|
||||||
|
struct rtr_socket rtr_tcp;
|
||||||
|
struct tr_socket tr_tcp;
|
||||||
|
struct tr_tcp_config tcp_config;
|
||||||
|
char ip_buf[INET6_ADDRSTRLEN];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rpki_config {
|
struct rpki_config {
|
||||||
struct proto_config c;
|
struct proto_config c;
|
||||||
struct cache_server remote;
|
list cache_list; /* (struct rpki_cache *) */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rpki_proto {
|
struct rpki_proto {
|
||||||
struct proto p;
|
struct proto p;
|
||||||
|
struct rtr_mgr_config *rtr_conf;
|
||||||
|
struct rtr_mgr_group *rtr_groups;
|
||||||
|
uint rtr_groups_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct rpki_cache *rpki_new_cache(void);
|
||||||
|
|
||||||
#endif /* _BIRD_RPKI_H_ */
|
#endif /* _BIRD_RPKI_H_ */
|
||||||
|
Loading…
Reference in New Issue
Block a user