]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Early integration of RTRlib into BIRD RPKI proto
authorPavel Tvrdík <pawel.tvrdik@gmail.cz>
Sun, 27 Sep 2015 22:15:52 +0000 (00:15 +0200)
committerPavel Tvrdík <pawel.tvrdik@gmail.cz>
Sun, 27 Sep 2015 22:34:10 +0000 (00:34 +0200)
lib/lists: add get_list_length(list *) function

lib/lists.c
lib/lists.h
proto/rpki/config.Y
proto/rpki/rpki.c
proto/rpki/rpki.h

index d323a4b68d5bbb64a2f6d53199ee5c72a38619ac..0606d2658584659b9325dc94cfb31b76a9e4073a 100644 (file)
@@ -175,3 +175,19 @@ add_tail_list(list *to, list *l)
   q->next = (node *) &to->null;
   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;
+}
index 80a4dc93731e3b0835fbe6bea9e3c53726dd81f0..50ce30635e8c2dc17a3fe57a25058d37f2f91641 100644 (file)
@@ -65,6 +65,7 @@ void rem2_node(node *);
 void add_tail_list(list *, list *);
 void init_list(list *);
 void insert_node(node *, node *);
+uint get_list_length(list *);
 #endif
 
 #endif
index b45e3a1d56aba78db0c2e4fe915e40d391b8be95..1e6b4a24b53944a1adad7a4d17df4b864248fa7f 100644 (file)
@@ -14,34 +14,65 @@ CF_DEFINES
 
 #define RPKI_CFG ((struct rpki_config *) this_proto)
 
+static struct rpki_cache *this_rpki_cache;
+
 CF_DECLS
 
-CF_KEYWORDS(RPKI, CACHE, SERVER, SERVERS)
+CF_KEYWORDS(RPKI, CACHE, LIST, PREFERENCE)
 
 CF_GRAMMAR
 
 CF_ADDTO(proto, rpki_proto)
 
-rpki_proto_start: proto_start RPKI {
+rpki_proto:
+   rpki_proto_start proto_name '{' rpki_proto_opts '}'
+
+rpki_proto_start:
+   proto_start RPKI {
      this_proto = proto_config_new(&proto_rpki, $1);
- }
+     init_list(&RPKI_CFG->cache_list);
+   }
+ ;
+
+rpki_proto_opts:
+   /* empty */
+ | rpki_proto_opts rpki_proto_item ';'
  ;
 
 rpki_proto_item:
    proto_item
- | CACHE SERVER ipa expr {
-       RPKI_CFG->remote.ip = $3;
-       RPKI_CFG->remote.port = $4;
- }
+ | CACHE LIST '{' rpki_cache_list '}'
  ;
 
-rpki_proto_opts:
+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_proto_opts rpki_proto_item ';'
+ | rpki_cache_opts rpki_cache_opts_item ';'
  ;
 
-rpki_proto:
-   rpki_proto_start proto_name '{' rpki_proto_opts '}'
+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
 
index 301769f3eb3345afbfc487d4f3c463c8302e3fa4..4d66532113952584bec2e0487c1325544afbf482 100644 (file)
 
 #define LOCAL_DEBUG
 
+#include <stdlib.h>
+#include <unistd.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 *
-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;
+
+  RPKI_TRACE(rpki, "------------- rpki_init -------------");
 
-  log(L_DEBUG "------------- rpki_init -------------");
+  ugly_hack_to_get_proto = P;
 
   /* 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
-rpki_start(struct proto *p)
+rpki_start(struct proto *P)
 {
-  struct proto_rpki *rpki = (struct proto_rpki *) p;
-  struct rpki_config *cf = (struct rpki_config *) (p->cf);
+  struct rpki_proto *rpki = (struct rpki_proto *) P;
+  struct rpki_config *cf = (struct rpki_config *) (P->cf);
+
+  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);
 
-  log(L_DEBUG "------------- rpki_start -------------");
+    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;
 }
 
 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;
 }
@@ -49,7 +162,7 @@ rpki_shutdown(struct proto *p)
 static int
 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;
 
   log(L_DEBUG "------------- rpki_reconfigure -------------");
index 6e79053afdf37a7afbe367683960fe2c751e0b5a..eaa94c0a7c67d31ebcc4e76fa80f39ff47419c80 100644 (file)
@@ -9,22 +9,47 @@
 #ifndef _BIRD_RPKI_H_
 #define _BIRD_RPKI_H_
 
+#include "rtrlib/rtrlib.h"
+
 #include "nest/bird.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;
-  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 proto_config c;
-  struct cache_server remote;
+  list cache_list;     /* (struct rpki_cache *) */
 };
 
 struct rpki_proto {
   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_ */