]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
RPKI: Add 'ignore max length' option
authorOndrej Zajicek (work) <santiago@crfreenet.org>
Sat, 10 Oct 2020 22:53:19 +0000 (00:53 +0200)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Sat, 10 Oct 2020 23:00:54 +0000 (01:00 +0200)
Add 'ignore max length' option to RPKI protocol, which ignores received
max length in ROA records and instead uses max value (32 or 128). This
may be useful for implementing loose RPKI check for blackholes.

doc/bird.sgml
proto/rpki/config.Y
proto/rpki/packets.c
proto/rpki/rpki.c
proto/rpki/rpki.h

index ffc22218d6964efcd01923780685f8c597c71880..aa16c2279c0288667db79cec1eb7631c33d9841d 100644 (file)
@@ -4826,6 +4826,11 @@ specify both channels.
         suppresses updating this value by a cache server.
         Default: 7200 seconds
 
+       <tag>ignore max length <m/switch/</tag>
+       Ignore received max length in ROA records and use max value (32 or 128)
+       instead. This may be useful for implementing loose RPKI check for
+       blackholes. Default: disabled.
+
         <tag>transport tcp</tag> Unprotected transport over TCP. It's a default
         transport. Should be used only on secure private networks.
         Default: tcp
index 924066f8e03967f4b0d0a11a1b85ff0a830e7e38..d6d326b814a8f3de77a1529361503977a549f68d 100644 (file)
@@ -32,7 +32,7 @@ rpki_check_unused_transport(void)
 CF_DECLS
 
 CF_KEYWORDS(RPKI, REMOTE, BIRD, PRIVATE, PUBLIC, KEY, TCP, SSH, TRANSPORT, USER,
-           RETRY, REFRESH, EXPIRE, KEEP)
+           RETRY, REFRESH, EXPIRE, KEEP, IGNORE, MAX, LENGTH)
 
 %type <i> rpki_keep_interval
 
@@ -79,6 +79,7 @@ rpki_proto_item:
      RPKI_CFG->expire_interval = $3;
      RPKI_CFG->keep_expire_interval = $2;
    }
+ | IGNORE MAX LENGTH bool { RPKI_CFG->ignore_max_length = $4; }
  ;
 
 rpki_keep_interval:
index e9d24fb8d6f05a1faaeb3499855c4074ae02bca4..dd11f997cc0e2a70decbe19111f7ccefa54cbe58 100644 (file)
@@ -729,12 +729,22 @@ rpki_prefix_pdu_2_net_addr(const struct pdu_header *pdu, net_addr_union *n)
 static int
 rpki_handle_prefix_pdu(struct rpki_cache *cache, const struct pdu_header *pdu)
 {
+  const struct rpki_config *cf = (void *) cache->p->p.cf;
+
   const enum pdu_type type = pdu->type;
   ASSERT(type == IPV4_PREFIX || type == IPV6_PREFIX);
 
   net_addr_union addr = {};
   rpki_prefix_pdu_2_net_addr(pdu, &addr);
 
+  if (cf->ignore_max_length)
+  {
+    if (type == IPV4_PREFIX)
+      addr.roa4.max_pxlen = IP4_MAX_PREFIX_LENGTH;
+    else
+      addr.roa6.max_pxlen = IP6_MAX_PREFIX_LENGTH;
+  }
+
   struct channel *channel = NULL;
 
   if (type == IPV4_PREFIX)
index 3e46b6d197a8c0c573309adf2e02c7da1bdfccb2..3ee46ae216a4483f1918771c6628e74f458bce2b 100644 (file)
@@ -639,18 +639,6 @@ rpki_shutdown(struct proto *P)
  *     RPKI Reconfiguration
  */
 
-static int
-rpki_try_fast_reconnect(struct rpki_cache *cache)
-{
-  if (cache->state == RPKI_CS_ESTABLISHED)
-  {
-    rpki_cache_change_state(cache, RPKI_CS_FAST_RECONNECT);
-    return SUCCESSFUL_RECONF;
-  }
-
-  return NEED_RESTART;
-}
-
 /**
  * rpki_reconfigure_cache - a cache reconfiguration
  * @p: RPKI protocol instance
@@ -666,6 +654,7 @@ rpki_try_fast_reconnect(struct rpki_cache *cache)
 static int
 rpki_reconfigure_cache(struct rpki_proto *p UNUSED, struct rpki_cache *cache, struct rpki_config *new, struct rpki_config *old)
 {
+  u8 try_reset = 0;
   u8 try_fast_reconnect = 0;
 
   if (strcmp(old->hostname, new->hostname) != 0)
@@ -685,6 +674,13 @@ rpki_reconfigure_cache(struct rpki_proto *p UNUSED, struct rpki_cache *cache, st
     CACHE_TRACE(D_EVENTS, cache, "Transport type changed");
     return NEED_RESTART;
   }
+
+  if (old->ignore_max_length != new->ignore_max_length)
+  {
+    CACHE_TRACE(D_EVENTS, cache, "Ignore max length changed");
+    try_reset = 1;
+  }
+
 #if HAVE_LIBSSH
   else if (new->tr_config.type == RPKI_TR_SSH)
   {
@@ -713,8 +709,26 @@ rpki_reconfigure_cache(struct rpki_proto *p UNUSED, struct rpki_cache *cache, st
   TEST_INTERVAL(expire, Expire);
 #undef TEST_INTERVAL
 
-  if (try_fast_reconnect)
-    return rpki_try_fast_reconnect(cache);
+  if (try_reset || try_fast_reconnect)
+  {
+    if (cache->state != RPKI_CS_ESTABLISHED)
+      return NEED_RESTART;
+
+    if (try_reset && !try_fast_reconnect)
+      rpki_cache_change_state(cache, RPKI_CS_RESET);
+
+    if (try_fast_reconnect)
+    {
+      if (try_reset)
+      {
+       /* Force reset during reconnect */
+       cache->request_session_id = 1;
+       cache->serial_num = 0;
+      }
+
+      rpki_cache_change_state(cache, RPKI_CS_FAST_RECONNECT);
+    }
+  }
 
   return SUCCESSFUL_RECONF;
 }
index 8972b33a50d8958045b675f2b67cd8b5e03cbea6..8a5c38fda4e1652dda2a5e502fc7574eb1be29c2 100644 (file)
@@ -125,6 +125,7 @@ struct rpki_config {
   u8 keep_refresh_interval:1;          /* Do not overwrite refresh interval by cache server update */
   u8 keep_retry_interval:1;            /* Do not overwrite retry interval by cache server update */
   u8 keep_expire_interval:1;           /* Do not overwrite expire interval by cache server update */
+  u8 ignore_max_length:1;              /* Ignore received max length and use MAX_PREFIX_LENGTH instead */
 };
 
 void rpki_check_config(struct rpki_config *cf);