<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<style>
html {
line-height: 1.2;
font-family: serif;
font-size: 0.9em;
color: black;
background-color: white;
}
body {
margin: 0;
margin-right: auto;
max-width: 36em;
padding: 1em;
hyphens: auto;
overflow-wrap: break-word;
text-rendering: optimizeLegibility;
font-kerning: normal;
}
@media print {
body {
background-color: transparent;
color: black;
font-size: 11pt;
}
p, h2, h3 {
orphans: 3;
widows: 3;
}
h2, h3, h4 {
page-break-after: avoid;
}
}
p {
margin: 1em 0;
}
a {
color: black;
}
a:visited {
color: black;
}
img {
max-width: 100%;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 1.4em;
}
h5, h6 {
font-size: 1em;
font-style: italic;
}
h6 {
font-weight: normal;
}
ol, ul {
padding-left: 1.7em;
margin-top: 1em;
}
li > ol, li > ul {
margin-top: 0;
}
blockquote {
margin: 0.5em;
padding-left: 0.5em;
border-left: 2px solid #e6e6e6;
color: #444;
}
code {
font-family: 'Lucida Console', monospace;
font-size: 95%;
margin: 0;
}
pre {
margin: 1em 0;
overflow: auto;
max-width: unset;
width: fit-content;
}
pre code {
padding: 0;
overflow: visible;
overflow-wrap: normal;
max-width: unset;
white-space: pre-wrap;
}
pre code span {
white-space: pre;
}
.sourceCode {
background-color: transparent;
overflow: visible;
}
code.diff span.kw,
code.diff span.dt {
font-weight: bold;
}
code.diff span.va {
background-color: rgba(192, 255, 192, 64);
color: rgb(0, 64, 0);
}
code.diff span.st {
background-color: rgba(255, 192, 192, 64);
color: rgb(64, 0, 0);
}
pre.diff {
background-color: rgb(240, 240, 240);
padding: 0.4em;
border: 1pt solid grey;
}
hr {
background-color: black;
border: none;
height: 1px;
margin: 1em 0;
}
table {
margin: 1em 0;
border-collapse: collapse;
width: 100%;
overflow-x: auto;
display: block;
font-variant-numeric: lining-nums tabular-nums;
}
table caption {
margin-bottom: 0.75em;
}
tbody {
margin-top: 0.5em;
border-top: 1px solid black;
border-bottom: 1px solid black;
}
th {
border-top: 1px solid black;
padding: 0.25em 0.5em 0.25em 0.5em;
}
td {
padding: 0.125em 0.5em 0.25em 0.5em;
}
header {
margin-bottom: 4em;
text-align: center;
}
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
q { quotes: "„" "”" "»" "«"; }
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
</style>
</head>
<body>
<p>Hi Jelle and Robert,</p>
<p>On Fri, Apr 04, 2025 at 08:11:47PM +0000, Jelle Luteijn via
Bird-users wrote:</p>
<blockquote>
<p>I have ASPA implemented. I use the following function: function
is_aspa_invalid(bool is_upstream) -> bool { if aspa_check(ASPAS,
bgp_path, is_upstream) = ASPA_INVALID then { print “Reject: ASPA
INVALID:”, net, ” “, bgp_path,” protocol: “, proto; return true; }</p>
<pre><code>return false;</code></pre>
<p>}</p>
<p>and I call this function in my filter for upstream as follows: if
is_aspa_invalid(false) then { reject; }</p>
<p>What I found, for ASPA the upstream question is, is your ASN the
upstream of the peer. In case of a transit the answer is no.</p>
</blockquote>
<p>with ASPA, you get several cases of what you are actually testing,
and the check itself has two variants, upstream and downstream.</p>
<p>The upstream check requires (kinda contradictorily), as you correctly
state, that the AS Path is upstream <em>only</em>.</p>
<p>In other words, for most of your clients, you do the upstream check.
You also do the upstream check for your lateral peers e.g. in IXPs,
unless you wanna use them as transit.</p>
<p>Only if the neighbor is your transit (or transit-like), you do the
downstream check.</p>
<blockquote>
<p>does somebody have an example configuration snippet for ASPA in BIRD
with rpki-client? I’ve read
https://bird.network.cz/?get_doc&v=20&f=bird-6.html but I’m
still not sure how the configuration in BIRD for an AS with two transit
providers (just upstreams, no downstreams) would look like…</p>
</blockquote>
<p>And with that, exactly as Jelle writes, you do the
<em>downstream</em> check for all your transits, i.e.</p>
<pre><code>if aspa_check_downstream(ASPAS) = ASPA_INVALID then reject "ASPA INVALID ", net, " ", bgp_path, " ", proto;</code></pre>
<p>Happy routing!<br />
Maria</p>
<p>–<br />
Maria Matejka (she/her) | BIRD Team Leader | CZ.NIC, z.s.p.o.</p>
</body>
</html>