Skip to content

Commit

Permalink
Add new feature: route order preference.
Browse files Browse the repository at this point in the history
  • Loading branch information
mxsasha committed Jan 31, 2023
1 parent e083aa4 commit 265e620
Show file tree
Hide file tree
Showing 61 changed files with 1,452 additions and 365 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ commands:
PATH=$PATH:/root/.cargo/bin/
$PYTHON_INTERPRETER -m venv venv
. venv/bin/activate
pip install -Ur requirements.txt
pip install -vUr requirements.txt
- save_cache:
paths:
Expand Down
22 changes: 21 additions & 1 deletion docs/admins/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,21 @@ Scope filter
|br| **Change takes effect**: after SIGHUP. Updating the status of
existing objects may take 10-15 minutes.

Route object preference
~~~~~~~~~~~~~~~~~~~~~~~
* ``route_object_preference.update_timer``: the time in seconds between
full updates of the
:doc:`route object preference </admins/route-object-preference>` status
for all objects in the database. Note that the status is already updated
on changes to objects as they are processed - this periodic process sets
the initial state and resolver small inconsistencies. This setting
has no effect unless at least one source has
``sources.{name}.route_object_preference`` set.
|br| **Default**: 3600 (1 hour)
|br| **Change takes effect**: after SIGHUP.

In addition to this, the route object preference of each source can be set
in ``sources.{name}.route_object_preference``, documented below.

Sources
~~~~~~~
Expand Down Expand Up @@ -655,7 +670,12 @@ Sources
this source. If set to ``true``, all objects will be considered in scope
for their scope filter status.
|br| **Default**: false, scope filter validation enabled.
|br| **Change takes effect**: after SIGHUP, within a few minutes
|br| **Change takes effect**: after SIGHUP, within a few minutes.
* ``sources.{name}.route_object_preference``: the
:doc:`route object preference </admins/route-object-preference>` for
this source. Higher number is a higher preference.
|br| **Default**: unset, not considered for route object preference.
|br| **Change takes effect**: after SIGHUP, after next periodic update.
* ``sources.{name}.suspension_enabled``: a boolean for whether this source
allows :doc:`suspension and reactivation of objects </admins/suspension>`.
Can only be enabled if `authoritative` is enabled.
Expand Down
145 changes: 145 additions & 0 deletions docs/admins/object-suppression.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
===========================
Object suppression overview
===========================

IRRd supports three methods to suppress objects:

* :doc:`RPKI </admins/rpki>`, where IRRd suppresses objects that are
invalid according to
`RFC6811 origin validation <https://tools.ietf.org/html/rfc6811>`_.
In addition, IRRd will create pseudo-IRR objects representing ROAs.
* The :doc:`scope filter </admins/scopefilter>`, which suppresses objects
matching certain configured prefixes and/or AS numbers.
* The :doc:`route object preference </admins/route-object-preference>`,
which suppresses objects that overlap with other route objects from
sources with a higher preference.

Suppression is a kind of pseudo delete/create: IRRd will act as if the
object was deleted, but it may become visible again later.
One exception is that suppressed objects may still be deleted and can
still conflict on primary key.
Unlike normal deletions and creations,
this visibility change may have an external cause, e.g. a new ROA created
by the address space holder, or a change in scope filter configuration.
Suppression can also apply to objects for which the instance
is not authoritative.

When IRRd evaluates suppression
-------------------------------
* RPKI and route object preference periodically update the status for all
relevant objects in the database. This resolves issues around temporary
inconsistencies and, for RPKI, is also the moment when the local ROA
storage is updated.
* For RPKI, this happens every ``rpki.roa_import_timer`` and for route object
preference every ``route_object_preference.update_timer``.
The scope filter updates all statuses on startup and then after any
configuration change.
* When IRRd receives objects from mirrors, in full imports or over NRTM,
the RPKI, scope filter and route preference status of these objects is updated.
* When users create an object for which the IRRd instance is authoritative,
the scope filter and RPKI will reject creation of a suppressed object.

Scope of suppression
--------------------
Suppressed objects are not visible in the responses to queries,
database exports, NRTM streams, or the event stream.

To aid in debugging, it is possible to include suppressed objects in some
query responses. On whois queries, you can use the ``!fno-rpki-filter``,
``!fno-scope-filter``, and/or ``!fno-route-preference-filter`` commands.
The filter is then disabled only for ``!r`` queries and all RIPE style
queries. In GraphQL ``rpslObjects`` queries, you can pass a specific list of
``rpkiStatus``, ``scopeFilterStatus``, and/or ``routePreferenceStatus``
to include in the response.

Recording in the local journal
------------------------------
Object suppression is reflected in the journal so that mirrors from
the IRRd instance follow with the suppression. This means that
IRRd does not record an ADD for suppressed objects, and if an existing
object changes from visible to suppressed, IRRd records a DEL.
If an already suppressed object is deleted by the mirror source,
IRRd does not record any journal entry.

An example: your IRRd
mirrors source DEMO from the authoritative source, you keep a local journal, and
a third party mirrors DEMO from you. When the authoritative source for
DEMO sends an NRTM ADD for an RPKI invalid route, that update is not
recorded in your IRRd's local journal. The third party that mirrors from
you will not see this ADD over NRTM.

If a ROA is added the next day that results in the route being RPKI valid
or not_found, an ADD is recorded in the local journal, and the third party
can pick up the change from an NRTM query to your IRRd. If that ROA is
deleted again, causing the route to return to RPKI invalid, a DEL is
recorded in your local journal.

Therefore, both the local state of your IRRd, and anyone mirroring from
your IRRd, will be up to date with the RPKI status.

For route object preference, there are cases where IRRd records an ADD
and then immediately a DEL for the same object.

Interaction between suppression statuses
----------------------------------------
Each suppression status is independent, but for the visibility in
the journal and query responses, IRRd considers the combined state:
an object is suppressed if any of the suppression methods see it as
suppressed.

Following on the previous example: if along with the RPKI state,
the object is out of scope according to the scope filter, IRRd will
not generate an ADD in the journal at any point, and the object
will never be visible in query responses.

Important considerations when enabling
--------------------------------------
When you enable one of these features for the first time, the periodic
task will usually take considerably longer than on subsequent runs.
On the first run, a large number of objects in the database may need to
be updated, whereas this number is much smaller on subsequent runs.
The same may occur after changing settings, if these change a large number
of objects.

While the import and validation is running, processing other
database changes may be delayed.

These large status changes may also generate a significant amount
of local journal entries, which are used to generate NRTM responses
for anyone mirroring any source from your IRRd. Depending on the
sources, there may be in the order of 100K-1M journal entries.
NRTM is really not designed for this scale, and therefore it is
likely faster to have mirrors reload their copy.

Writing such huge numbers of changes to the journal also takes
considerable time.
If you are planning to require mirrors to reload their copies,
you may want to disable the ``keep_journal``
setting on one or more sources for the initial status update.
This speeds up the process dramatically, but means you must
make sure all mirrors reload their copy after you have re-enabled
the journal. Otherwise, they will desynchronise silently.

Temporary inconsistencies
-------------------------
There are a number situations that can cause temporary inconsistencies for
RPKI and route object preference, because multiple processes depend on
each other's state. These are usually small, and automatically resolved
on the next periodic update, which considers the state of the whole database.

For example:
when you enable RPKI-aware mode and **at the same time** add a new source,
the objects for the new source may not have the correct RPKI status
initially. This happens because in the new source import process, no ROAs
are visible, and to the periodic ROA update, the objects in the new source
are not visible yet. This situation automatically resolves itself upon
the next periodic ROA update, but may cause objects that should be marked
RPKI-invalid to be included in responses in the mean time.

Similarly: a case where two mirror imports with different route object
preferences run at the precise same time, and both include a `route` object
for there same prefix. IRRd will record both as visible, because neither
mirror process was able to see the other's object. This also resolves
on the next periodic full route object preference update.
Generally, the timing of these processes is slightly different, making
this a rare issue.
13 changes: 7 additions & 6 deletions docs/admins/object-validation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ However, most current IRR databases violate these RFCs in some
ways, meaning some flexibility is needed.

In addition to the validations as described below, IRRd supports
an :doc:`RPKI-aware mode </admins/rpki>` where objects are also
validated against ROAs.
:doc:`object suppression </admins/object-suppression>` where objects are also
filtered or validated against ROAs, a scope filter, or other route objects.


General requirements
Expand All @@ -19,13 +19,13 @@ The general requirements for validation are:
* Any objects submitted to IRRd directly (i.e. not from mirrors)
should always be entirely valid. If they are not, the end user
can fix their object and continue from there.
* The NTTCOM database has some legacy objects which require more
* Many databases have some legacy objects which require more
leniency with an initial import, but we aim to be as restrictive
as reasonably possible. It should not be possible to update invalid
objects without correcting their issues.
authoritative objects without correcting their issues.
* Mirrors contain wildly variant objects, so IRRd performs the minimal
level of validation needed to correctly index and query them.
* Under no condition may IRRd provide responses to any query, which
* IRRd must never provide responses to any query, which
are missing certain objects because indexed data could not be extracted
from them, without logging errors about failing to import these objects.
* If objects are received from mirrors that can not be accepted, e.g.
Expand Down Expand Up @@ -100,6 +100,7 @@ The ``rpki-ov-state`` attribute, which is used to indicate the
:doc:`RPKI validation status </admins/rpki>`, is always discarded from all
incoming objects. Where relevant, it is added to the output of queries.
This applies to authoritative and non-authoritative sources.
This attribute is not visible over NRTM and in exports.

key-cert objects
^^^^^^^^^^^^^^^^
Expand All @@ -114,7 +115,7 @@ last-modified
^^^^^^^^^^^^^
For authoritative objects, the ``last-modified`` attribute is set when
the object is created or updated. Any existing ``last-modified`` values are
discarded. This timestamp is not updated for changes in RPKI validation
discarded. This timestamp is not updated for changes in object suppression
status. This attribute is visible over NRTM and in exports.

By default, this attribute is only added when an object is changed or
Expand Down
95 changes: 95 additions & 0 deletions docs/admins/route-object-preference.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
=======================
Route object preference
=======================

IRRd supports a route object preference, where `route(6)` objects can
be suppressed if they overlap with other `route(6)` objects from sources
with a higher route object preference.

.. note::
This document only contains details specific to the scope filter, and is
meant to complement the
:doc:`object suppression overview </admins/object-suppression>`.

.. contents::
:backlinks: none
:local:

Configuring route object preference
-----------------------------------
You can enable route object preference by setting
``sources.{name}.route_object_preference`` on at least one source.
This is a number, where higher numbers have higher preference. See the
:doc:`configuration documentation </admins/configuration>` for the
exact syntax.

You can exclude sources by **not** setting
``sources.{name}.route_object_preference``.
Objects from these sources are always seen as visible.

To disable this feature, set ``route_object_preference`` for all sources
to the same preference to reset the state of all objects to visible.
Once the periodic
import has updated this, unset ``sources.{name}.route_object_preference``
for all sources to disable the update process.

Validation
----------
* In route object preference, each `route(6)` object is assigned a preference
from its source's ``sources.{name}.route_object_preference`` setting.
* For the objects with a preference: if there is an overlapping
`route(6)` object with a higher preference, the lower preference object
is suppressed.
* Overlap means that the prefixes of the objects are an exact match, more
specific, or less specific.
* If two overlapping objects have the same preference, both are visible
(assuming there are no further overlaps).
* Origin ASes are not considered.
* Objects from sources without a preference setting are always visible and
otherwise completely ignored in the validation process. They are also not
included when considering suppression of other objects.

For example, let's say the preferences are: TEST-H1 and TEST-H2 at
priority 900, TEST-M at 200, TEST-L at 100, TEST-N with no preference,
and the following objects exist:

* A: TEST-H1 192.0.0.0/23 AS65530
* B: TEST-H2 192.0.0.0/24 AS65530
* C: TEST-L 192.0.0.0/23 AS65530
* D: TEST-M 192.0.0.0/22 AS65530
* E: TEST-M 192.0.1.0/24 AS65530
* F: TEST-L 192.0.3.0/24 AS65530
* G: TEST-N 192.0.0.0/22 AS65530

In this case objects C, D, E and F will be suppressed.
C, D and E all overlap directly with A and/or B, and A and B have a higher
preference than all others. A and B have an identical preference so their
objects will both be visible. Object F overlaps with object D, and object D
has a higher preference, therefore object F is also suppressed.
Object G remains visible and is otherwise ignored, as it has no
preference set, so it has no impact on the visibility of other objects.

Log messages and journal order
------------------------------
RPKI and scope filter status are determined per object,
shortly after parsing. Route preference status is rather difference:
it is determined for all affected prefixes just before committing.
This has some practical consequences that may lead to initially
confusing log messages or journal entries.

In RPKI and scope filter, the status of an object can be determined
by evaluating only that object, and the IRRd configuration and/or ROA table.
However, for route preference, an object's status depends on which
other objects exist in other sources. Also, uniquely, one object
being added or deleted, may cause the state of an entirely different
object to change, which was not part of the current change set.

When evaluating the status just before a transaction commit, IRRd
will log a line like:
`route preference updated for a subset of 15 added/removed/changed
routes: 2 regular objects made visible, 8 regular objects suppressed,
0 objects from excluded sources made visible`.
Important to note is that the 15 added/removed/changed routes do not
have to be the same objects as the 2 objects made visible, and the 8 made
suppressed. Similarly, processing NRTM changes from one source, may
lead to journal entries for objects of an entirely different source.
Loading

0 comments on commit 265e620

Please sign in to comment.