Hello all,

I am in the process of adding RPKI/ROA (RFC 6810/RFC 6811) support to
OpenBGPd. I have an almost working PoC but I'd like to hear your opinion
and discuss implementation details with misc@ before going further.

First of all, here is what RPKI-enabled bgpd.conf looks like :
----8<--------------
AS 65530
router-id 10.0.0.102

fib-update yes

Transitv4="10.0.0.1"

validator "2001:db8::102" {
        port 8282
        poll-interval 300
}

neighbor $Transitv4 {
        descr "ROA Lab"
        remote-as 65531
        announce none
}

#match from any rpki-invalid set localpref 80
deny from any rpki-invalid
match from any rpki-valid set localpref 120
match from any rpki-not-found set localpref 99
----8<--------------

Then what "bgpctl show rib" looks like :
(with "match from any rpki-invalid set localpref 80")
----8<--------------
# bgpctl sho rib
flags: * = Valid, > = Selected, I = via IBGP, A = Announced, S = Stale,
v = RPKI valid, i = RPKI invalid, u = RPKI unknown
origin: i = IGP, e = EGP, ? = Incomplete

flags  destination          gateway          lpref   med aspath origin
u*>    10.0.0.0/20          10.0.0.1            99     0 65530 i
u*>    10.0.0.0/24          10.0.0.1            99     0 65530 i
i*>    93.187.228.0/24      10.0.0.1            80     0 65530 i
v*>    185.22.128.0/22      10.0.0.1           120     0 65530 i
----8<--------------

(with "deny from any rpki-invalid")
----8<--------------
# bgpctl sho rib
flags: * = Valid, > = Selected, I = via IBGP, A = Announced, S = Stale,
v = RPKI valid, i = RPKI invalid, u = RPKI unknown
origin: i = IGP, e = EGP, ? = Incomplete

flags  destination          gateway          lpref   med aspath origin
u*>    10.0.0.0/20          10.0.0.1            99     0 65530 i
u*>    10.0.0.0/24          10.0.0.1            99     0 65530 i
v*>    185.22.128.0/22      10.0.0.1           120     0 65530 i
----8<--------------

So, we have a new keyword ("validator") that is used to define a
validation server. Inside that, we have 3 parameters :
- port (defaults to 323 - between 1-65535) : tcp port of the validator
- poll-interval (defaults to 3600 - between 60-3600) : number of seconds
before polling the validator for changes.

That's for the visible part :)
Now, let's look under the hood.

OpenBGPd has now a rpki-client, which connects to a validator, get
validated objects from the validator and put them in a list of validated
ROA (VRP). It then compares every prefix with the content of the VRP and
filters accordingly.

The validator connection is handled by session.c, it is close to
neighbor connection process. It has 4 states :
- init : the beginning
- connecting : validator was contacted and is processing the 3-way handshake
- syncing : the rpki-client is receiving ROAs.
- synced : the rpki-client is now waiting for updates from the validator
(or until poll-interval expires).

While syncing the rpki-client sends each objects to rde.c. rde.c stores
the objects in a RB-list (one for IPv4 prefixes, one for IPv6 prefixes)
and removes if it is a withdrawal. when the rpki-client receives a "End
of Data" PDU, it sends a command to rde.c to start validation of known
peer prefixes (from rib[0]).

The VRP size is ~12k, the RIB size is ~530k so that's a lot to check.

If you have any implementation advice, I'm all hear :)
The major difficulty is to no put too much load on the router when
comparing between VRP and RIB and how to update FIB when VRP changes.

Regards,
Denis

Reply via email to