]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
Protocolary updates for release 1.7.0.experimental main 1.7.0.experimental
authorAlberto Leiva Popper <ydahhrk@gmail.com>
Thu, 16 Jul 2026 01:50:19 +0000 (19:50 -0600)
committerAlberto Leiva Popper <ydahhrk@gmail.com>
Thu, 16 Jul 2026 01:50:19 +0000 (19:50 -0600)
12 files changed:
configure.ac
docker/Dockerfile
docs/_config.yml
docs/intro-fort.md
docs/usage.md
man/fort.8
src/asn1/asn1c/ASProviderAttestation.c
src/asn1/asn1c/ProviderASSet.c
src/config.c
src/extension.c
src/rtr/pdu_handler.c
test/rtr/pdu_handler_test.c

index ac9ac0441e5b3b89c0ecee3a3d6653e3652e6880..798bc880ee96fd7e290e745561d6389b736995f2 100644 (file)
@@ -2,7 +2,7 @@
 # Process this file with autoconf to produce a configure script.
 
 AC_PREREQ([2.69])
-AC_INIT([fort],[1.6.8],[validadorfort@fortproject.net])
+AC_INIT([fort],[1.7.0.experimental],[validadorfort@fortproject.net])
 AC_CONFIG_SRCDIR([src/main.c])
 AM_INIT_AUTOMAKE([subdir-objects])
 
index 96e459170d9ced0ae141ecb955473119c8028f89..2a6540ee01d682e5a0bc72aa5e4f61de4a1e25d6 100644 (file)
@@ -1,6 +1,6 @@
 #--- Alpine build container ---
 FROM alpine:latest AS builder
-ARG FORT_VERSION=1.6.8
+ARG FORT_VERSION=1.7.0.experimental
 
 # Install compiler and dependencies
 RUN apk --update --no-cache add build-base autoconf automake pkgconfig jansson-dev check-dev \
index 77e9e0c1e28b84159efe9aac2cb0a30d1bd733b7..fde557f765ab820757dfe167d600c071e39778be 100644 (file)
@@ -8,7 +8,7 @@ defaults:
       layout: "default"
       image: "/img/logo_validador_og.png"
 
-fort-latest-version: 1.6.8
+fort-latest-version: 1.7.0.experimental
 plugins:
   - jekyll-seo-tag
   - jekyll-sitemap
index fe4ccc72ae137c0d66ebdc1ae5eaf0c5c16d93be..2f9b76e0f7725fe700b749c7230fab4e045dd638 100644 (file)
@@ -20,26 +20,26 @@ Fort is a command-line application intended for UNIX operating systems, written
 | Issue | Title | Urgency | Due release |
 |-------|-------|---------|-------------|
 | [issue82](https://github.com/NICMx/FORT-validator/issues/82) | Reach 100% RFC 9286 compliance | <span class="urgency-critical">Critical</span> | <a href="https://github.com/NICMx/FORT-validator/milestone/12">2.0.0</a> |
+| [issue119](https://github.com/NICMx/FORT-validator/issues/119) | Review IRIs to file names transition | <span class="urgency-high">High</span> | <a href="https://github.com/NICMx/FORT-validator/milestone/12">2.0.0</a> |
+| [issue121](https://github.com/NICMx/FORT-validator/issues/121) | Refactor validation and operation logging | <span class="urgency-high">High</span> | <a href="https://github.com/NICMx/FORT-validator/milestone/12">2.0.0</a> |
 | [issue149](https://github.com/NICMx/FORT-validator/issues/149) | Lock the cache during updates | <span class="urgency-high">High</span> | <a href="https://github.com/NICMx/FORT-validator/milestone/12">2.0.0</a> |
+| [issue97](https://github.com/NICMx/FORT-validator/issues/97) | Add "incidence" fields for every nonfatal RFC incompliance | <span class="urgency-medium">Medium</span> | <a href="https://github.com/NICMx/FORT-validator/milestone/12">2.0.0</a> |
 | [issue113](https://github.com/NICMx/FORT-validator/issues/113) | Detect and properly respond to subtler RRDP session desynchronization | <span class="urgency-medium">Medium</span> | <a href="https://github.com/NICMx/FORT-validator/milestone/12">2.0.0</a> |
 | [issue124](https://github.com/NICMx/FORT-validator/issues/124) | Atomize output files (`--output.roa` and `--output.bgpsec`) | <span class="urgency-medium">Medium</span> | <a href="https://github.com/NICMx/FORT-validator/milestone/12">2.0.0</a> |
+| [issue126](https://github.com/NICMx/FORT-validator/issues/126) | Exhaustive URL validation | <span class="urgency-medium">Medium</span> | <a href="https://github.com/NICMx/FORT-validator/milestone/12">2.0.0</a> |
 | [issue129](https://github.com/NICMx/FORT-validator/issues/129) | Rethink the thread pools | <span class="urgency-medium">Medium</span> | <a href="https://github.com/NICMx/FORT-validator/milestone/12">2.0.0</a> |
+| [issue131](https://github.com/NICMx/FORT-validator/issues/131) | Remove the Ghostbusters code | <span class="urgency-low">Low</span> | <a href="https://github.com/NICMx/FORT-validator/milestone/12">2.0.0</a> |
 | [issue114](https://github.com/NICMx/FORT-validator/issues/114) | Support automatic TA key rollover | <span class="urgency-very-high">Very High</span> | <a href="https://github.com/NICMx/FORT-validator/milestone/13">2.0.1</a> |
 | [issue58](https://github.com/NICMx/FORT-validator/issues/58) | Fort's validation produces no router keys | <span class="urgency-very-high">Very High</span> | <a href="https://github.com/NICMx/FORT-validator/milestone/14">2.0.2</a> |
-| [issue132](https://github.com/NICMx/FORT-validator/issues/132) | Implement RTRv2 | <span class="urgency-very-high">Very High</span> | - |
 | [issue116](https://github.com/NICMx/FORT-validator/issues/116) | SLURM review | <span class="urgency-high">High</span> | - |
-| [issue118](https://github.com/NICMx/FORT-validator/issues/118) | Implement validation re-reconsidered | <span class="urgency-high">High</span> | - |
-| [issue119](https://github.com/NICMx/FORT-validator/issues/119) | Review IRIs to file names transition | <span class="urgency-high">High</span> | - |
 | [issue120](https://github.com/NICMx/FORT-validator/issues/120) | Error messages review | <span class="urgency-high">High</span> | - |
-| [issue121](https://github.com/NICMx/FORT-validator/issues/121) | Refactor validation and operation logging | <span class="urgency-high">High</span> | - |
 | [issue72](https://github.com/NICMx/FORT-validator/issues/72) | Encrypt RTR | <span class="urgency-medium">Medium</span> | - |
 | [issue73](https://github.com/NICMx/FORT-validator/issues/73) | Minimize probability of RTR session ID and serial reuse | <span class="urgency-medium">Medium</span> | - |
 | [issue90](https://github.com/NICMx/FORT-validator/issues/90) | Add "metadata" section to json output | <span class="urgency-medium">Medium</span> | - |
 | [issue91](https://github.com/NICMx/FORT-validator/issues/91) | Add "ta" field to ROAs in json output | <span class="urgency-medium">Medium</span> | - |
-| [issue97](https://github.com/NICMx/FORT-validator/issues/97) | Add "incidence" fields for every nonfatal RFC incompliance | <span class="urgency-medium">Medium</span> | - |
 | [issue117](https://github.com/NICMx/FORT-validator/issues/117) | Warn on maxLength defined on SLURM | <span class="urgency-medium">Medium</span> | - |
+| [issue118](https://github.com/NICMx/FORT-validator/issues/118) | Implement validation re-reconsidered | <span class="urgency-medium">Medium</span> | - |
 | [issue125](https://github.com/NICMx/FORT-validator/issues/125) | ASN.1 review | <span class="urgency-medium">Medium</span> | - |
-| [issue126](https://github.com/NICMx/FORT-validator/issues/126) | Exhaustive URL validation | <span class="urgency-medium">Medium</span> | - |
 | [issue127](https://github.com/NICMx/FORT-validator/issues/127) | Stream RRDP files | <span class="urgency-medium">Medium</span> | - |
 | [issue128](https://github.com/NICMx/FORT-validator/issues/128) | Reuse TCP connections for HTTP requests to same server | <span class="urgency-medium">Medium</span> | - |
 | [issue130](https://github.com/NICMx/FORT-validator/issues/130) | Improve documentation | <span class="urgency-medium">Medium</span> | - |
@@ -47,8 +47,5 @@ Fort is a command-line application intended for UNIX operating systems, written
 | [issue152](https://github.com/NICMx/FORT-validator/issues/152) | compliance issue: Fort accepts GeneralizedTime with fractional seconds | <span class="urgency-medium">Medium</span> | - |
 | [issue153](https://github.com/NICMx/FORT-validator/issues/153) | Not enforcing DER encoding | <span class="urgency-medium">Medium</span> | - |
 | [issue40](https://github.com/NICMx/FORT-validator/issues/40) | failure scenarios, monitoring and glibc recommendations | <span class="urgency-low">Low</span> | - |
-| [issue42](https://github.com/NICMx/FORT-validator/issues/42) | reload feature: restart validation on SIGHUP | <span class="urgency-low">Low</span> | - |
-| [issue70](https://github.com/NICMx/FORT-validator/issues/70) | Do a quick temporary offline validation to prevent `No Data Available` | <span class="urgency-low">Low</span> | - |
 | [issue123](https://github.com/NICMx/FORT-validator/issues/123) | New invocation mode: Validate single file | <span class="urgency-low">Low</span> | - |
-| [issue131](https://github.com/NICMx/FORT-validator/issues/131) | Implement vCard validation | <span class="urgency-low">Low</span> | - |
 | [issue134](https://github.com/NICMx/FORT-validator/issues/134) | Add support RFC 9589 (On the Use of the CMS Signing-Time Attribute in RPKI Signed Objects) | <span class="urgency-low">Low</span> | - |
index 9899ce74ced834be1815f5db3ca0003c17823d03..6e2d4ac52ce3de2183f8ce285f304e1f3016de89 100644 (file)
@@ -29,6 +29,7 @@ description: Guide to use arguments of FORT Validator.
        17. [`--server.interval.retry`](#--serverintervalretry)
        18. [`--server.interval.expire`](#--serverintervalexpire)
        18. [`--server.deltas.lifetime`](#--serverdeltaslifetime)
+       18. [`--server.max-rtr-version`](#--servermax-rtr-version)
        18. [`--prometheus.port`](#--prometheusport)
        19. [`--slurm`](#--slurm)
        20. [`--log.enabled`](#--logenabled)
@@ -42,6 +43,7 @@ description: Guide to use arguments of FORT Validator.
        28. [`--validation-log.level`](#--validation-loglevel)
        29. [`--validation-log.output`](#--validation-logoutput)
        30. [`--validation-log.color-output`](#--validation-logcolor-output)
+       30. [`--aspa.max-providers`](#--aspamax-providers)
        31. [`--validation-log.file-name-format`](#--validation-logfile-name-format)
        32. [`--validation-log.facility`](#--validation-logfacility)
        33. [`--validation-log.tag`](#--validation-logtag)
@@ -60,6 +62,7 @@ description: Guide to use arguments of FORT Validator.
        42. [`--http.proxy`](#--httpproxy)
        43. [`--output.roa`](#--outputroa)
        44. [`--output.bgpsec`](#--outputbgpsec)
+       44. [`--output.aspa`](#--outputaspa)
        45. [`--output.format`](#--outputformat)
        46. [`--asn1-decode-max-stack`](#--asn1-decode-max-stack)
        48. [`--thread-pool.server.max`](#--thread-poolservermax)
@@ -95,13 +98,14 @@ description: Guide to use arguments of FORT Validator.
        [--work-offline=true|false]
        [--daemon=true|false]
        [--server.address=<sequence of strings>]
-       [--server.port=<unsigned integer or service string>]
+       [--server.port=<port>]
        [--server.backlog=<unsigned integer>]
        [--server.interval.validation=<unsigned integer>]
        [--server.interval.refresh=<unsigned integer>]
        [--server.interval.retry=<unsigned integer>]
        [--server.interval.expire=<unsigned integer>]
        [--server.deltas.lifetime=<unsigned integer>]
+       [--server.max-rtr-version=<unsigned integer>]
        [--prometheus.port=<unsigned integer>]
        [--rsync.enabled=true|false]
        [--rsync.priority=<unsigned integer>]
@@ -120,7 +124,7 @@ description: Guide to use arguments of FORT Validator.
        [--http.low-speed-time=<unsigned integer>]
        [--http.max-file-size=<unsigned integer>]
        [--http.ca-path=<directory>]
-       [--http.proxy=<HTTPS URL>]
+       [--http.proxy=<URI>]
        [--log.enabled=true|false]
        [--log.output=syslog|console]
        [--log.level=error|warning|info|debug]
@@ -135,13 +139,16 @@ description: Guide to use arguments of FORT Validator.
        [--validation-log.facility=auth|authpriv|cron|daemon|ftp|lpr|mail|news|user|uucp|local0|local1|local2|local3|local4|local5|local6|local7]
        [--validation-log.file-name-format=global-url|local-path|file-name]
        [--validation-log.color-output=true|false]
+       [--aspa.max-providers=<unsigned integer>]
        [--output.roa=<file>]
        [--output.bgpsec=<file>]
+       [--output.aspa=<file>]
        [--output.format=csv|json]
        [--asn1-decode-max-stack=<unsigned integer>]
        [--init-tals=true|false]
        [--init-as0-tals=true|false]
        [--thread-pool.server.max=<unsigned integer>]
+       [--file-type=roa|mft|gbr|cer|crl]
 ```
 
 If an argument is specified more than once, the last one takes precedence:
@@ -174,9 +181,9 @@ Usage: {{ page.command }}
        [--init-as0-tals=true|false]
                (Fetch the currently-known AS0 TAL files into --tal)
        [--thread-pool.server.max=<unsigned integer>]
-               (Maximum number of active threads (one thread per RTR client) that can live at the thread pool)
-       [--thread-pool.validation.max=<unsigned integer>]
-               (Maximum number of active threads (one thread per TAL) that can live at the thread pool)
+               (Number of threads in the RTR client request thread pool. Also known as the maximum number of client requests the RTR server will be able to handle at the same time.)
+       [--file-type=roa|mft|gbr|cer|crl]
+               (Parser for --mode=print)
 {% endhighlight %}
 
 The slightly larger usage message is `man {{ page.command }}` and the large usage message is this documentation.
@@ -195,9 +202,9 @@ Usage: {{ page.command }}
         [--usage]
         [--version]
        ...
-        [--log.file-name-format=global-url|local-path|file-name]
-        [--output.roa=<file>]
-        [--output.bgpsec=<file>]
+       [--init-as0-tals=true|false]
+       [--thread-pool.server.max=<unsigned integer>]
+       [--file-type=roa|mft|gbr|cer|crl]
 {% endhighlight %}
 
 ### `--version`
@@ -405,7 +412,7 @@ See the corresponding manual page from your operating system (likely `man 2 list
 - **Type:** Integer
 - **Availability:** `argv` and JSON
 - **Default:** 3600
-- **Range:** [60, [`UINT_MAX`](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html)]
+- **Range:** [60, 7 days]
 
 Number of seconds Fort will sleep between validation cycles, when in [`server`](#--mode) mode.
 
@@ -456,8 +463,8 @@ See [RFC 8210, section 6](https://tools.ietf.org/html/rfc8210#section-6).
 
 - **Type:** Integer
 - **Availability:** `argv` and JSON
-- **Default:** 21600 (6 hours)
-- **Range:** [1, [`UINT_MAX`](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html)]
+- **Default:** 6
+- **Range:** [1, 1000]
 
 RTR delta lifetime, measured in validation cycles.
 
@@ -467,6 +474,23 @@ Fort stores the information necessary to serve these deltas in the cache. `--ser
 
 If a router lags behind, to the point Fort has already deleted the deltas it needs to update the router's snapshot, Fort will have to fall back to fetch the entire latest snapshot instead.
 
+### `--server.max-rtr-version`
+
+- **Type:** Integer
+- **Availability:** `argv` and JSON
+- **Default:** 0
+- **Range:** [0, 2]
+
+Maximum RTR version the server will be willing to negotiate with RTR clients.
+
+RTRv0 is [RFC6810](https://datatracker.ietf.org/doc/html/rfc6810), RTRv1 is [RFC8210](https://datatracker.ietf.org/doc/html/rfc8210), and at time of writing, RTRv2 is [draft-ietf-sidrops-8210bis-26](https://datatracker.ietf.org/doc/html/draft-ietf-sidrops-8210bis-26).
+
+RTRv0 servers Prefix VRPs. RTRv1 adds Router Keys, and RTRv2 adds ASPAs.
+
+At present, this value defaults to v0 because Fort's validation [currently yields no router keys](https://github.com/NICMx/FORT-validator/issues/58), and the ASPA specification is still receiving updates. Fort 1.7.0.experimental's RTRv2 implementation is draft-ietf-sidrops-8210bis-25, not 26.
+
+The default value is expected to grow as the implementation matures.
+
 ### `--prometheus.port`
 
 - **Type:** Integer
@@ -534,6 +558,17 @@ Include ANSI color codes in the logging? Meant to ease human consumption. Only a
 
 See [Logging > Configuration > Color output](logging.html#color-output).
 
+### `--aspa.max-providers`
+
+- **Type:** Integer
+- **Availability:** `argv` and JSON
+- **Default:** 4000
+- **Range:** [0, 16380]
+
+Maximum number of providers each customerASID is allowed to declare across all RPKI trees during each validation cycle.
+
+Customers that exceed this provider count will be invalidated.
+
 ### `--log.file-name-format`
 
 - **Type:** Enumeration (`global-url`, `local-path`, `file-name`)
@@ -839,32 +874,42 @@ https_proxy=https://example.com:1234 fort --tal=/path/to/tal
 - **Availability:** `argv` and JSON
 - **Default:** `NULL` (disabled)
 
-File where the ROAs (found during each validation run) will be stored. See [`--output.format`](#--outputformat).
+Assigns a file where Fort will print the valid VRPs found after each validation run.
+
+If the file already exists, it will be overwritten. If it doesn't exist, it will be created. To print to standard output, assign a hyphen (`-`).
 
-If the file already exists, it will be overwritten. If it doesn't exist, it will be created. To print to standard output, use a hyphen (`-`). If the RTR server is [enabled](#--mode), then the ROAs will be printed every [`--server.interval.validation`](#--serverintervalvalidation) secs.
+Sample output when [`--output.format`](#--outputformat) equals `csv`:
 
-When `--output.format` equals `csv`, each line of the result is printed in the following order: _AS, Prefix, Max prefix length_. The first line contains the column names.
+```csv
+ASN,Prefix,Max prefix length
+AS1000,192.0.2.0/24,24
+AS10001,203.0.113.0/28,30
+AS24047,2001:db8::/64,96
+```
 
-When `--output.format` equals `json`, each element is printed in an object array of `roas`:
+Sample output when `--output.format` equals `json`:
 
-{% highlight json %}
+```json
 {
        "roas": [
                {
-                       "asn": "AS64496",
-                       "prefix": "198.51.100.0/24",
-                       "maxLength": 24
-               },
-               {
-                       "asn": "AS64496",
-                       "prefix": "2001:DB8::/32",
-                       "maxLength": 48
+                       "asn": "AS1000",
+                       "prefix": "192.0.2.0/24",
+                       "maxLength": 30
+               }, {
+                       "asn": "AS10001",
+                       "prefix": "203.0.113.0/28",
+                       "maxLength": 30
+               }, {
+                       "asn": "AS24047",
+                       "prefix": "2001:db8::/64",
+                       "maxLength": 96
                }
        ]
 }
-{% endhighlight %}
+```
 
-If `--output.roa` is omitted, the ROAs are not printed.
+If absent, VRPs are not printed.
 
 ### `--output.bgpsec`
 
@@ -903,6 +948,31 @@ When `--output.format` equals `json`, each element is printed in an object array
 
 If `--output.bgpsec` is ommited, then the BGPsec Router Keys are not printed.
 
+### `--output.aspa`
+
+- **Type:** String (Path to file)
+- **Availability:** `argv` and JSON
+- **Default:** `NULL` (disabled)
+
+Assigns a file where Fort will print the valid ASPAs found after each validation run. ASPAs are always printed in JSON format.
+
+If the file already exists, it will be overwritten. If it doesn't exist, it will be created. To print to standard output, assign a hyphen (`-`).
+
+Each element is identifier by its customerASID, and its value is an array of provider ASIDs:
+
+```json
+{
+       "aspa" : {
+               "2": [ 10000, 10001, 10002 ],
+               "1513": [ 10000 ],
+               "65500": [ 4221, 61971, 87645 ],
+               "16777217": [ 39, 410, 503, 8018622 ]
+       }
+}
+```
+
+If absent, ASPAs are not printed.
+
 ### `--output.format`
 
 - **Type:** Enumeration (`csv`, `json`)
@@ -1022,7 +1092,8 @@ The configuration options are mostly the same as the ones from the `argv` interf
                },
                "deltas": {
                        "<a href="#--serverdeltaslifetime">lifetime</a>": 2
-               }
+               },
+               "<a href="#--servermax-rtr-version">max-rtr-version</a>": 0
        },
 
        "prometheus": {
@@ -1036,7 +1107,6 @@ The configuration options are mostly the same as the ones from the `argv` interf
                        "<a href="#--rsyncretrycount">count</a>": 1,
                        "<a href="#--rsyncretryinterval">interval</a>": 4
                },
-               "<a href="#--rsynctransfer-timeout">transfer-timeout</a>": 900,
                "<a href="#rsyncprogram">program</a>": "rsync",
                "<a href="#rsyncarguments-recursive">arguments-recursive</a>": [
                        "-rtz",
@@ -1045,16 +1115,19 @@ The configuration options are mostly the same as the ones from the `argv` interf
                        "--contimeout=20",
                        "--max-size=20MB",
                        "--timeout=15",
+                       "--exclude=.*",
                        "--include=*/",
                        "--include=*.cer",
+                       "--include=*.roa",
+                       "--include=*.asa",
+                       "--include=*.mft",
                        "--include=*.crl",
                        "--include=*.gbr",
-                       "--include=*.mft",
-                       "--include=*.roa",
                        "--exclude=*",
                        "$REMOTE",
                        "$LOCAL"
-               ]
+               ],
+               "<a href="#--rsynctransfer-timeout">transfer-timeout</a>": 900
        },
 
        "http": {
@@ -1094,6 +1167,10 @@ The configuration options are mostly the same as the ones from the `argv` interf
                "<a href="#--validation-logfile-name-format">file-name-format</a>": "global-url",
                "<a href="#--validation-logcolor-output">color-output</a>": false
        },
+       
+       "aspa": {
+               "<a href="#--aspamax-providers">max-providers</a>": 4000
+       },
 
        "<a href="#incidences">incidences</a>": [
                {
@@ -1118,8 +1195,9 @@ The configuration options are mostly the same as the ones from the `argv` interf
        ],
 
        "output": {
-               "<a href="#--outputroa">roa</a>": null,
-               "<a href="#--outputbgpsec">bgpsec</a>": null,
+               "<a href="#--outputroa">roa</a>": "vrps.csv",
+               "<a href="#--outputbgpsec">bgpsec</a>": "rks.csv",
+               "<a href="#--outputbgpsec">aspa</a>": "aspas.json",
                "<a href="#--outputformat">format</a>": "csv"
        },
 
@@ -1182,7 +1260,7 @@ Name of the program needed to invoke an rsync file transfer.
 
 - **Type:** String array
 - **Availability:** JSON only
-- **Default:** `[ "-rtz", "--delete", "--omit-dir-times", "--contimeout=20", "--max-size=20MB", "--timeout=15", "--include=*/", "--include=*.cer", "--include=*.crl", "--include=*.gbr", "--include=*.mft", "--include=*.roa", "--exclude=*", "$REMOTE", "$LOCAL" ]`
+- **Default:** `[ "-rtz", "--delete", "--omit-dir-times", "--contimeout=20", "--max-size=20MB", "--timeout=15", "--exclude=.*", "--include=*/", "--include=*.cer", "--include=*.roa", "--include=*.asa", "--include=*.mft", "--include=*.crl", "--include=*.gbr", "--exclude=*", "$REMOTE", "$LOCAL" ]`
 
 Arguments needed by [`rsync.program`](#rsyncprogram) to perform a recursive rsync.
 
@@ -1202,7 +1280,7 @@ A listing of actions to be performed by validation upon encountering certain err
 - **Type:** Boolean (`true`, `false`)
 - **Availability:** `argv` and JSON
 
-> ![img/warn.svg](img/warn.svg) This argument **is DEPRECATED**.
+> ![img/warn.svg](img/warn.svg) This argument is deprecated.
 
 Does nothing as of Fort 1.6.0.
 
@@ -1212,7 +1290,7 @@ Does nothing as of Fort 1.6.0.
 - **Availability:** `argv` and JSON
 - **Range:** [0, [`UINT_MAX`](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html)]
 
-> ![img/warn.svg](img/warn.svg) This argument **is DEPRECATED**.
+> ![img/warn.svg](img/warn.svg) This argument is deprecated.
 
 Does nothing as of Fort 1.6.0.
 
@@ -1221,7 +1299,7 @@ Does nothing as of Fort 1.6.0.
 - **Type:** Enumeration (`strict`, `root`, `root-except-ta`)
 - **Availability:** `argv` and JSON
 
-> ![img/warn.svg](img/warn.svg) This argument **is DEPRECATED**.
+> ![img/warn.svg](img/warn.svg) This argument is deprecated.
 
 Does nothing as of Fort 1.6.0.
 
@@ -1230,7 +1308,7 @@ Does nothing as of Fort 1.6.0.
 - **Type:** String array
 - **Availability:** JSON only
 
-> ![img/warn.svg](img/warn.svg) This argument **is DEPRECATED**.
+> ![img/warn.svg](img/warn.svg) This argument is deprecated.
 
 Does nothing as of Fort 1.6.0.
 
@@ -1240,6 +1318,6 @@ Does nothing as of Fort 1.6.0.
 - **Availability:** `argv` and JSON
 - **Range:** [1, 100]
 
-> ![img/warn.svg](img/warn.svg) This argument **is DEPRECATED**.
+> ![img/warn.svg](img/warn.svg) This argument is deprecated.
 
 Does nothing as of Fort 1.6.0.
index 5bd5eb6aed25d8d0c7e51eeeeddf6709343d1c51..0b871ef08b85393265b5772b13f02a8a5ebd9669 100644 (file)
@@ -1,4 +1,4 @@
-.TH fort 8 "2026-05-29" "v1.6.8" "FORT validator"
+.TH fort 8 "2026-07-14" "v1.7.0.experimental" "FORT validator"
 
 .SH NAME
 fort \- RPKI validator and RTR server
@@ -115,9 +115,9 @@ Arguments needed by
 to perform a recursive rsync. The arguments are specified as a JSON string
 array; its default value is:
 [ "-rtz", "--delete", "--omit-dir-times", "--contimeout=20", "--max-size=20MB",
-"--timeout=15", "--include=*/", "--include=*.cer", "--include=*.crl",
-"--include=*.gbr", "--include=*.mft", "--include=*.roa", "--exclude=*",
-"$REMOTE", "$LOCAL" ]
+"--timeout=15", "--exclude=.*", "--include=*/", "--include=*.cer",
+"--include=*.roa", "--include=*.asa", "--include=*.mft", "--include=*.crl",
+"--include=*.gbr", "--exclude=*", "$REMOTE", "$LOCAL" ]
 .P
 FORT will replace "$REMOTE" with the remote URL it needs to download, and
 "$LOCAL" with the target local directory where the file is supposed to be
@@ -452,6 +452,20 @@ If a router lags behind, to the point Fort has already deleted the deltas it nee
 .RE
 .P
 
+.B \-\-server.max\-rtr\-version=\fIUNSIGNED_INTEGER\fR
+.RS 4
+Maximum RTR version the server will be willing to negotiate with RTR clients.
+.P
+RTRv0 is RFC6810, RTRv1 is RFC8210, and at time of writing, RTRv2 is draft-ietf-sidrops-8210bis-26.
+.P
+RTRv0 servers Prefix VRPs. RTRv1 adds Router Keys, and RTRv2 adds ASPAs.
+.P
+At present, this value defaults to v0 because Fort's validation currently yields no router keys (issue #58), and the ASPA specification is still receiving updates. Fort 1.7.0.experimental's RTRv2 implementation is draft-ietf-sidrops-8210bis-25, not 26.
+.P
+The default value is expected to grow as the implementation matures.
+.RE
+.P
+
 .B \-\-prometheus.port=\fIUNSIGNED_INTEGER\fR
 .RS 4
 TCP port the Prometheus server will be bound to.
@@ -950,41 +964,50 @@ By default, it has a value of \fI900\fR.
 .RE
 .P
 
+.B \-\-aspa.max\-providers=\fIUNSIGNED_INTEGER\fR
+.RS 4
+Maximum number of providers each customerASID is allowed to declare across all RPKI trees during each validation cycle.
+.P
+Customers that exceed this provider count will be invalidated.
+.RE
+.P
+
 .B \-\-output.roa=\fIFILE\fR
 .RS 4
-File where the ROAs will be printed in the configured format (see
-\fI--output.format\fR).
+Assigns a file where Fort will print the valid VRPs found after each validation run.
 .P
-When the \fIFILE\fR is specified, its content will be overwritten by the
-resulting ROAs of the validation (if FILE doesn't exists, it'll be created).
+If the file already exists, it will be overwritten. If it doesn't exist, it will be created. To print to standard output, assign a hyphen.
 .P
-When \fI--output.format=csv\fR (which is the default value), then each line of
-the result is printed in the following order: AS, Prefix, Max prefix length; the
-first line contains those column descriptors.
+Sample output when \fI--output.format=csv\fR:
 .P
-When \fI--output.format=json\fR, then each element is printed inside an object
-array of "roas"; ie:
 .nf
-{
-  "roas": [
-    {
-      "asn": "AS64496",
-      "prefix": "198.51.100.0/24",
-      "maxLength": 24
-    },
-    {
-      "asn": "AS64496",
-      "prefix": "2001:DB8::/32",
-      "maxLength": 48
-    }
-  ]
-}
+       ASN,Prefix,Max prefix length
+       AS1000,192.0.2.0/24,24
+       AS10001,203.0.113.0/28,30
+       AS24047,2001:db8::/64,96
 .fi
 .P
-In order to print the ROAs at console, use a hyphen as the \fIFILE\fR value, eg.
-.B \-\-output.roa=-
+Sample output when \fI--output.format=json\fR:
 .P
-By default, it has no value set.
+.nf
+       { "roas": [
+               {
+                       "asn": "AS1000",
+                       "prefix": "192.0.2.0/24",
+                       "maxLength": 30
+               }, {
+                       "asn": "AS10001",
+                       "prefix": "203.0.113.0/28",
+                       "maxLength": 30
+               }, {
+                       "asn": "AS24047",
+                       "prefix": "2001:db8::/64",
+                       "maxLength": 96
+               }
+       ] }
+.fi
+.P
+If absent, VRPs are not printed.
 .RE
 .P
 
@@ -1006,6 +1029,7 @@ Subject Public Key Info; the first line contains those column descriptors.
 .P
 When \fI--output.format=json\fR, then each element is printed inside an object
 array of "router-keys"; ie:
+.P
 .nf
 {
   "router-keys": [
@@ -1031,6 +1055,29 @@ By default, it has no value set.
 .RE
 .P
 
+.B \-\-output.aspa=\fIFILE\fR
+.RS 4
+Assigns a file where Fort will print the valid ASPAs found after each validation run. ASPAs are always printed in JSON format.
+.P
+If the file already exists, it will be overwritten. If it doesn't exist, it will be created. To print to standard output, assign a hyphen.
+.P
+Each element is identifier by its customerASID, and its value is an array of provider ASIDs:
+.P
+.nf
+{
+       "aspa" : {
+               "2": [ 10000, 10001, 10002 ],
+               "1513": [ 10000 ],
+               "65500": [ 4221, 61971, 87645 ],
+               "16777217": [ 39, 410, 503, 8018622 ]
+       }
+}
+.fi
+.P
+If absent, ASPAs are not printed.
+.RE
+.P
+
 .B \-\-output.format=\fIcsv\fR|\fIjson\fR
 .RS 4
 Output format for \fI--output.roa\fR and \fI--output.bgpsec\fR.
@@ -1111,6 +1158,7 @@ validating every 30 minutes, and printing the ROAs CSV in a file.
 .RS 4
 This is an example of a valid JSON configuration file with all its members set
 to a specific value:
+.P
 .nf
 {
   "tal": "/tmp/fort/tal/",
@@ -1253,6 +1301,7 @@ to a specific value:
 .RS 4
 This is an example of a SLURM file with some prefix filters and assertions, as
 well as some dummy Router Keys (BGPsec) info:
+.P
 .nf
 
 {
index 7e383a5571cc9bd0794a5eef062eb146c378de43..aa8c54b1b138df4489f867a8adbce52390a3514b 100644 (file)
@@ -39,8 +39,8 @@ static asn_TYPE_member_t asn_MBR_ASProviderAttestation_1[] = {
                (ASN_TAG_CLASS_CONTEXT | (0 << 2)),
                +1,     /* EXPLICIT tag at current level */
                &asn_DEF_INTEGER,
-               0,
-               { 0, 0, 0 },
+               NULL,
+               { NULL, NULL, NULL },
                &asn_DFL_2_cmp_0,       /* Compare DEFAULT 0 */
                &asn_DFL_2_set_0,       /* Set DEFAULT 0 */
                "version"
@@ -49,18 +49,18 @@ static asn_TYPE_member_t asn_MBR_ASProviderAttestation_1[] = {
                (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
                0,
                &asn_DEF_ASId,
-               0,
-               { 0, 0, 0 },
-               0, 0, /* No default value */
+               NULL,
+               { NULL, NULL, NULL },
+               NULL, NULL, /* No default value */
                "customerASID"
                },
        { ATF_NOFLAGS, 0, offsetof(struct ASProviderAttestation, providers),
                (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)),
                0,
                &asn_DEF_ProviderASSet,
-               0,
-               { 0, 0, 0 },
-               0, 0, /* No default value */
+               NULL,
+               { NULL, NULL, NULL },
+               NULL, NULL, /* No default value */
                "providers"
                },
 };
@@ -89,7 +89,7 @@ asn_TYPE_descriptor_t asn_DEF_ASProviderAttestation = {
        asn_DEF_ASProviderAttestation_tags_1,   /* Same as above */
        sizeof(asn_DEF_ASProviderAttestation_tags_1)
                /sizeof(asn_DEF_ASProviderAttestation_tags_1[0]), /* 1 */
-       { 0, 0, SEQUENCE_constraint },
+       { NULL, NULL, SEQUENCE_constraint },
        asn_MBR_ASProviderAttestation_1,
        3,      /* Elements count */
        &asn_SPC_ASProviderAttestation_specs_1  /* Additional specs */
index 5444945f6e2fe874eeb31fc6933ae5226baae777..9ac31c191ccd7da81f8a9549f129bf5041f444e8 100644 (file)
@@ -14,9 +14,9 @@ asn_TYPE_member_t asn_MBR_ProviderASSet_1[] = {
                (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
                0,
                &asn_DEF_ASId,
-               0,
-               { 0, 0, 0 },
-               0, 0, /* No default value */
+               NULL,
+               { NULL, NULL, NULL },
+               NULL, NULL, /* No default value */
                ""
                },
 };
index 675fff6c5540601afcf5b2de36ae69a0aede67d1..0f29e8e1c9efc2781d2b63a2cdd9aa720b2c1223 100644 (file)
@@ -445,7 +445,7 @@ static const struct option_field options[] = {
                .name = "server.max-rtr-version",
                .type = &gt_uint,
                .offset = offsetof(struct rpki_config, server.max_rtr_version),
-               .doc = "Maximum RTR version to serve (0-2).",
+               .doc = "Maximum RTR version the server will be willing to negotiate with RTR clients",
                .min = 0,
                .max = 2,
        },
@@ -744,7 +744,7 @@ static const struct option_field options[] = {
                .name = "aspa.max-providers",
                .type = &gt_uint,
                .offset = offsetof(struct rpki_config, aspa.max_providers),
-               .doc = "Maximum allowed providers per customer",
+               .doc = "Maximum number of providers each customerASID is allowed to declare across all RPKI trees during each validation cycle",
                .min = 0,
                .max = 16380u,
        },
@@ -764,7 +764,7 @@ static const struct option_field options[] = {
                .name = "output.roa",
                .type = &gt_string,
                .offset = offsetof(struct rpki_config, output.roa),
-               .doc = "File where ROAs will be stored, use '-' to print at console",
+               .doc = "File where VRPs will be stored. ('-' for stdout)",
                .arg_doc = "<file>",
                .json_null_allowed = true,
        }, {
@@ -772,7 +772,7 @@ static const struct option_field options[] = {
                .name = "output.bgpsec",
                .type = &gt_string,
                .offset = offsetof(struct rpki_config, output.bgpsec),
-               .doc = "File where BGPsec Router Keys will be stored, use '-' to print at console",
+               .doc = "File where BGPsec Router Keys will be stored. ('-' for stdout)",
                .arg_doc = "<file>",
                .json_null_allowed = true,
        }, {
@@ -780,7 +780,7 @@ static const struct option_field options[] = {
                .name = "output.aspa",
                .type = &gt_string,
                .offset = offsetof(struct rpki_config, output.aspa),
-               .doc = "Path to file where ASPAs will be stored. ('-' for stdout)",
+               .doc = "File where ASPAs will be stored. ('-' for stdout)",
                .arg_doc = "<file>",
                .json_null_allowed = true,
        }, {
index 17cd06b65a938bb5e42ab3b1ba1d4c2655d947e4..d897e9c5109162c5d2a26575a2f183ba0471a076 100644 (file)
@@ -125,7 +125,7 @@ ku2json(void const *ext)
        json_t *child;
 
        ku_len = ASN1_STRING_length(ku);
-       if (ku_len != 1 || ku_len != 2)
+       if (ku_len != 1 && ku_len != 2)
                return NULL;
 
        parent = json_obj_new();
index d148687d8130573135359a8119b587b2acb30166..139b6a903c4a7a9a38bd12d2b48be036494c2230 100644 (file)
@@ -222,7 +222,7 @@ again:      n = fread(buf, size, 1, file);
 static int
 send_serial(struct rtr_stream *stream, serial_t serial)
 {
-       FILE *file = 0;
+       FILE *file = NULL;
        unsigned char *buf;
        unsigned char const *chunk;
        int error;
@@ -248,7 +248,7 @@ end:        free(buf);
 static int
 send_aspas(int fd, uint8_t ver, serial_t serial)
 {
-       FILE *file = 0;
+       FILE *file = NULL;
        unsigned char buf[8];
        unsigned char const *chunk;
        int error;
index 52779a98671b7ee95f9cd2454a1ffbf5095fd599..7e431b7e0b62086b5e134c244ee67894ff01371b 100644 (file)
@@ -17,7 +17,7 @@
 #include "types/router_key.c"
 #include "types/serial.c"
 
-unsigned int deltas_lifetime = 5;
+static unsigned int deltas_lifetime = 5;
 
 MOCK(config_get_local_repository, char const *, "tmp", void)
 MOCK_UINT(config_get_deltas_lifetime, deltas_lifetime, void)
@@ -116,7 +116,7 @@ mock_commit(struct db_table *tbl)
        return session;
 }
 
-uint16_t
+static uint16_t
 mock_serial1(void)
 {
        struct db_table *tbl = db_table_create();
@@ -124,7 +124,7 @@ mock_serial1(void)
        return mock_commit(tbl);
 }
 
-void
+static void
 mock_serial2(void)
 {
        struct db_table *tbl = db_table_create();
@@ -133,7 +133,7 @@ mock_serial2(void)
        mock_commit(tbl);
 }
 
-void
+static void
 mock_serial3(void)
 {
        struct db_table *tbl = db_table_create();
@@ -141,7 +141,7 @@ mock_serial3(void)
        mock_commit(tbl);
 }
 
-void
+static void
 mock_serial4(void)
 {
        struct db_table *tbl = db_table_create();