RFC 2622
Routing Policy Specification Language (RPSL)
RFC 2622: Routing Policy Specification Language (RPSL) π
Network Working Group, June 1999 ποΈ Category: Standards Track β¨
Eight authors wrote this one, each with their own affiliation π«Ά:
- C. Alaettinoglu, USC/Information Sciences Institute
- C. Villamizar, Avici Systems
- E. Gerich, At Home Network
- D. Kessens, Qwest Communications
- D. Meyer, University of Oregon
- T. Bates, Cisco Systems
- D. Karrenberg, RIPE NCC
- M. Terpstra, Bay Networks
It obsoletes RFC 2280 π₯, and its header doesn't list any RFC it updates. Okay, on to the good stuff π
Status of this Memo π
okay so this doc specifies an Internet standards track protocol for the whole Internet community π, and it literally asks for discussion and suggestions for improvements π¬. For the standardization state and status of this protocol, check the "Internet Official Protocol Standards" (STD 1) π§. Distribution of this memo is unlimited, so share it with your bestie π«Ά
Copyright Notice Β©οΈ
Copyright (C) The Internet Society (1999). All Rights Reserved.
Abstract π¦
RPSL lets a network operator specify routing policies at various levels in the Internet hierarchy, for example at the Autonomous System (AS) level π. Policies can also be detailed enough that low level router configurations can be generated from them π₯. And RPSL is extensible: new routing protocols and new protocol features can be introduced at any time π
Table of Contents π
1 Introduction 3
2 RPSL Names, Reserved Words, and Representation 4
3 Contact Information 7
3.1 mntner Class . . . . . . . . . . . . . . . . . . . . . . . . 7
3.2 person Class . . . . . . . . . . . . . . . . . . . . . . . . 10
3.3 role Class . . . . . . . . . . . . . . . . . . . . . . . . . 11
4 route Class 12
5 Set Classes 13
5.1 as-set Class . . . . . . . . . . . . . . . . . . . . . . . . 14
5.2 route-set Class. . . . . . . . . . . . . . . . . . . . . . . 15
5.3 Predefined Set Objects . . . . . . . . . . . . . . . . . . . 17
5.4 Filters and filter-set Class . . . . . . . . . . . . . . . . 17
5.5 rtr-set Class. . . . . . . . . . . . . . . . . . . . . . . . 22
5.6 Peerings and peering-set Class . . . . . . . . . . . . . . . 24
6 aut-num Class 27
6.1 import Attribute: Import Policy Specification . . . . . . . 27
6.1.1 Action Specification . . . . . . . . . . . . . . . . . . 28
6.2 export Attribute: Export Policy Specification . . . . . . . 29
6.3 Other Routing Protocols, Multi-Protocol Routing Protocols,
and Injecting Routes Between Protocols . . . . . . . . . . . . 29
6.4 Ambiguity Resolution . . . . . . . . . . . . . . . . . . . . 31
6.5 default Attribute: Default Policy Specification . . . . . . 33
6.6 Structured Policy Specification. . . . . . . . . . . . . . . 33
7 dictionary Class 37
7.1 Initial RPSL Dictionary and Example Policy Actions and
Filters. . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
8 Advanced route Class 45
8.1 Specifying Aggregate Routes. . . . . . . . . . . . . . . . . 45
8.1.1Interaction with policies in aut-num class. . . . . . . . 49
8.1.2Ambiguity resolution with overlapping aggregates. . . . . 50
8.2 Specifying Static Routes . . . . . . . . . . . . . . . . . . 52
9 inet-rtr Class 52
10 Extending RPSL 54
10.1 Extensions by changing the dictionary class . . . . . . . . 54
10.2 Extensions by adding new attributes to existing classes . . 55
10.3 Extensions by adding new classes . . . . . . . . . . . . . 55
10.4 Extensions by changing the syntax of existing RPSL
attributes. . . . . . . . . . . . . . . . . . . . . . . . . . 55
11 Security Considerations 56
12 Acknowledgements 56
References 56
A Routing Registry Sites 59
B Grammar Rules 59
C Changes from RFC 2280 67
D Authors' Addresses 68
Full Copyright Statement 69
1 Introduction β¨
okay so this memo is the reference doc for the Routing Policy Specification Language (RPSL) π. RPSL lets a network operator specify routing policies at various levels in the Internet hierarchy, for example at the Autonomous System (AS) level. Policies can be detailed enough that low level router configurations can be generated from them. RPSL is extensible, so new routing protocols and new protocol features can be introduced at any time π¦
RPSL is a replacement for the current Internet policy specification language known as RIPE-181 [6] or RFC-1786 [7]. RIPE-81 [8] was the first language deployed in the Internet for specifying routing policies, and it was later replaced by RIPE-181 [6]. Using RIPE-181 in the real world made it clear that certain policies cannot be specified, so a more enhanced and generalized language was needed π. RPSL fixes RIPE-181's limitations π
RPSL was designed so that a view of the global routing policy can live in a single cooperatively maintained distributed database, which improves the integrity of the Internet's routing πΈ. RPSL is not designed to be a router configuration language π ββοΈ. Instead, router configurations can be generated from the description of the policy for one autonomous system (aut-num class) combined with the description of a router (inet-rtr class). The inet-rtr class mainly provides the router ID, the autonomous system number of the router, and the interfaces and peers of the router. You then combine that with a global database that maps AS sets to ASes (as-set class), and origin ASes and route sets to route prefixes (route and route-set classes). A well-populated RPSL database helps with goals like router configurations that protect against accidental (or malicious) distribution of inaccurate routing information, verification of the Internet's routing, and aggregation boundaries beyond a single AS π
RPSL is object oriented, which means objects contain pieces of policy and administrative information π§. These objects are registered in the Internet Routing Registry (IRR) by the authorized organizations. The registration process is beyond the scope of this document, so check [1, 17, 4] for more details on the IRR π
In the following sections, we present the classes used to define various policy and administrative objects π. The "mntner" class defines entities authorized to add, delete and modify a set of objects. The "person" and "role" classes describe technical and administrative contact personnel. Autonomous systems (ASes) are specified using the "aut-num" class, and routes are specified using the "route" class. Sets of objects can be defined using the "as-set", "route-set", "filter-set", "peering-set", and "rtr-set" classes. The "dictionary" class provides the extensibility of the language, and the "inet-rtr" class is used to specify routers. Many of these classes were originally defined in earlier documents [6, 13, 16, 12, 5], and they've all been enhanced π
This document is self-contained, but the reader is encouraged to read RIPE-181 [7] and the associated documents [13, 16, 12, 5]. They give significant background on the motivation and underlying principles behind RIPE-181 and, as a result, RPSL π«Ά For a tutorial on RPSL, read the RPSL applications document [4] π
2. RPSL Names, Reserved Words, and Representation β¨
okay so every class has a bunch of attributes π, which are basically little boxes that hold info about the objects in that class. Attributes can be mandatory (they have to be defined for every object of the class) or optional (you can skip them π ). Attributes can also be single or multiple valued. Each object gets uniquely identified by a set of attributes called the class "key" π.
Every attribute value has a type. Here are the big ones πΈ. RPSL is case insensitive π, and only ASCII characters are allowed π.
<object-name>: lots of RPSL objects have a name π. An object name is made of letters, digits, the underscore "_", and the hyphen "-". The first character has to be a letter, and the last character has to be a letter or a digit. These words are reserved by RPSL, so you can't use them as names:
any as-any rs-any peeras
and or not
atomic from to at action accept announce except refine
networks into inbound outbound
Some prefixes are reserved for certain object types, so the name has to match the vibe π§:
- Names starting with
as-are reserved for as set names. - Names starting with
rs-are reserved for route set names. - Names starting with
rtrs-are reserved for router set names. - Names starting with
fltr-are reserved for filter set names. - Names starting with
prng-are reserved for peering set names.
<as-number>: an AS number x is written as ASx. So AS 226 becomes AS226 β¨.
<ipv4-address>: an IPv4 address is four integers from 0 to 255, separated by dots ".". For example, 128.9.128.5 is a valid IPv4 address π¦. For the rest of this document, we may refer to IPv4 addresses as IP addresses, so don't be confused if you see that π.
<address-prefix>: an address prefix is an IPv4 address, then a slash /, then an integer from 0 to 32. These are valid:
128.9.128.5/32, 128.9.0.0/16, 0.0.0.0/0
These are invalid, bestie, because 0 and 128.9 are not strings with four integers in them π
ββοΈ:
0/0, 128.9/16
<address-prefix-range>: an address prefix range is an address prefix followed by an optional range operator. The range operators are below, and they're honestly so iconic π.
^-is the exclusive more specifics operator. It means all the more specifics of the address prefix, but NOT the address prefix itself. For example,128.9.0.0/16^-contains all the more specifics of128.9.0.0/16excluding128.9.0.0/16.^+is the inclusive more specifics operator. It means all the more specifics of the address prefix, INCLUDING the address prefix itself. For example,5.0.0.0/8^+contains all the more specifics of5.0.0.0/8including5.0.0.0/8.^n, where n is an integer, means all the length n specifics of the address prefix. For example,30.0.0.0/8^16contains all the more specifics of30.0.0.0/8that are length 16, such as30.9.0.0/16.^n-m, where n and m are integers, means all the length n to length m specifics of the address prefix. For example,30.0.0.0/8^24-32contains all the more specifics of30.0.0.0/8that are length 24 to 32, such as30.9.9.96/28.
Range operators can also go on address prefix sets. When they do, they distribute over every member of the set. For example, if rs-foo is a route-set (we'll get there later π«Ά), then rs-foo^+ contains all the inclusive more specifics of every prefix in rs-foo.
Now for the rules, and yes, they matter π€. It is an error to follow a range operator with another range operator. For example, 30.0.0.0/8^24-28^+ is an error π. However, a range operator CAN be applied to an address prefix set that already has address prefix ranges in it. For example, {30.0.0.0/8^24-28}^27-30 is totally fine π. In that case, the outer operator ^n-m distributes over the inner operator ^k-l and turns into ^max(n,k)-m, but only if m is greater than or equal to max(n,k). Otherwise, that prefix gets deleted from the set ποΈ.
A few equivalences to memorise, periodt π :
^nis equivalent to^n-n.prefix/l^+is equivalent toprefix/l^l-32.prefix/l^-is equivalent toprefix/l^(l+1)-32.{prefix/l^n-m}^+is equivalent to{prefix/l^n-32}.{prefix/l^n-m}^-is equivalent to{prefix/l^(n+1)-32}.
And here are some examples, because they're so satisfying to look at β¨:
{128.9.0.0/16^+}^- == {128.9.0.0/16^-}
{128.9.0.0/16^-}^+ == {128.9.0.0/16^-}
{128.9.0.0/16^17}^24 == {128.9.0.0/16^24}
{128.9.0.0/16^20-24}^26-28 == {128.9.0.0/16^26-28}
{128.9.0.0/16^20-24}^22-28 == {128.9.0.0/16^22-28}
{128.9.0.0/16^20-24}^18-28 == {128.9.0.0/16^20-28}
{128.9.0.0/16^20-24}^18-22 == {128.9.0.0/16^20-22}
{128.9.0.0/16^20-24}^18-19 == {}
<date>: a date is an eight digit integer in the form YYYYMMDD. YYYY is the year, MM is the month (01 through 12), and DD is the day of the month (01 through 31). All dates are in UTC unless it says otherwise π. For example, June 24, 1996 is 19960624 π.
<email-address>: this one is as described in RFC-822 [10] π§.
<dns-name>: this one is as described in RFC-1034 [17] π.
<nic-handle>: a NIC handle is a uniquely assigned identifier word. Routing, address allocation, and other registries use it to refer to contact information without any confusion π«Ά. The person and role classes map NIC handles to actual person names and contact info.
<free-form>: a sequence of ASCII characters. That's it, that's the whole vibe π .
<X-name>: a name of an object of type X. So <mntner-name> is a name of a mntner object π₯.
<registry-name>: a name of an IRR registry π¦. The routing registries are listed in Appendix A.
An attribute value can also be a list of one of these types πΈ. You make a list by separating the members with commas ",". For example, "AS1, AS2, AS3, AS4" is a list of AS numbers. Now, here's the tea β: being list valued and being multiple valued are NOT the same thing π. A multiple valued attribute has more than one value, and each of those values may or may not be a list. A single valued attribute, on the other hand, can still have a list value.
An RPSL object is written as a list of attribute-value pairs π. Each pair goes on its own line. The attribute name starts at column 0, followed by a colon ":", and then the attribute's value. The attribute with the same name as the object's class should be written first π₯°. The object's representation ends when you hit a blank line. An attribute's value can be split across multiple lines by starting each continuation line with a space, a tab, or a plus ('+') character. The plus character for line continuation even lets attribute values contain blank lines π€―. You may add more spaces after the continuation character to make things easier to read. The order of the attribute-value pairs matters, bestie β οΈ.
An object's description can contain comments π¬. A comment can go anywhere in the object's definition. It starts at the first "#" character on a line and runs until the end of that line. White space is fine to use for readability β¨.
An integer can be written in three ways π’:
- The C programming language notation, like
1or12345. - A sequence of four 1-octet integers (each from 0 to 255) separated by dots ".", like
1.1.1.1or255.255.0.0. In this case, the 4-octet integer is formed by joining these 1-octet integers, most significant to least significant. - A sequence of two 2-octet integers (each from 0 to 65535) separated by colons ":", like
3561:70or3582:10. In this case, the 4-octet integer is formed by joining these 2-octet integers, most significant to least significant.
3. Contact Information
the mntner, person, and role classes, plus the admin-c, tech-c, mnt-by, changed, and source attributes of all classes, are all about contact information π. The mntner class also holds the authentication information needed to create, delete, and update other objects π. These classes don't specify routing policies, and each registry may have different or extra requirements for them π« . We're showing the common denominator here, for completeness, based on the RIPE database implementation [16] π¦. Please check your routing registry for the latest spec of these classes and attributes, because it can change π . The "Routing Policy System Security" document [20] goes deeper into the authentication and authorization model π₯.
3.1 mntner Class
Okay so the mntner class is basically the bouncer π It holds the authentication info needed to create, delete, and update RPSL objects. A provider has to make a mntner object before they can create any RPSL objects at all π The attributes are shown in Figure 1, and this class was first described in [13].
The mntner attribute is mandatory and it's the class key π Its value is an RPSL name. The auth attribute tells you which scheme will be used to identify and authenticate update requests from this maintainer. Its syntax looks like this:
auth: <scheme-id> <auth-info>
E.g.
auth: NONE
Attribute Value Type
mntner <object-name> mandatory, single-valued, class key
descr <free-form> mandatory, single-valued
auth see description in text mandatory, multi-valued
upd-to <email-address> mandatory, multi-valued
mnt-nfy <email-address> optional, multi-valued
tech-c <nic-handle> mandatory, multi-valued
admin-c <nic-handle> optional, multi-valued
remarks <free-form> optional, multi-valued
notify <email-address> optional, multi-valued
mnt-by list of <mntner-name> mandatory, multi-valued
changed <email-address> <date> mandatory, multi-valued
source <registry-name> mandatory, single-valued
Figure 1: mntner Class Attributes
auth: CRYPT-PW dhjsdfhruewf
auth: MAIL-FROM .*@ripe\.net
The <scheme-id>'s that are currently defined are NONE, MAIL-FROM, PGP-KEY and CRYPT-PW β¨ The <auth-info> is the extra info a particular scheme needs. For MAIL-FROM it's a regular expression that matches valid email addresses π§ For CRYPT-PW it's a password in UNIX crypt format ποΈ And for PGP-KEY it's a pointer to a key-certif object [22] that holds the user's PGP public key. If you specify multiple auth attributes, an update request that satisfies any one of them is authenticated to be from the maintainer. Main character energy, honestly π
The upd-to attribute is an email address. If someone makes an unauthorized update attempt on an object this maintainer looks after, an email message gets sent to that address π¨ The mnt-nfy attribute is also an email address, and a notification message gets forwarded to it whenever an object maintained by this maintainer is added, changed or deleted π
The descr attribute is a short, free-form description of the object π The tech-c attribute is a technical contact NIC handle, aka the person you contact for technical problems like misconfiguration π οΈ The admin-c attribute is an administrative contact NIC handle. The remarks attribute is free text for explanations or clarifications. The notify attribute is an email address where notifications about changes to this object should be sent. The mnt-by attribute is a list of mntner object names, and changes to this object are governed by any of the maintainer objects referenced there π¦ The changed attribute records who last changed the object and when. Its syntax looks like this:
changed: <email-address> <YYYYMMDD>
E.g.
changed: johndoe@terabit-labs.nn 19900401
The <email-address> identifies the person who made the last change, and <YYYYMMDD> is the date of that change π The source attribute specifies the registry where the object is registered πΈ Figure 2 shows an example mntner object, and this one uses UNIX crypt format password authentication.
mntner: RIPE-NCC-MNT
descr: RIPE-NCC Maintainer
admin-c: DK58
tech-c: OPS4-RIPE
upd-to: ops@ripe.net
mnt-nfy: ops-fyi@ripe.net
auth: CRYPT-PW lz1A7/JnfkTtI
mnt-by: RIPE-NCC-MNT
changed: ripe-dbm@ripe.net 19970820
source: RIPE
Figure 2: An example mntner object.
The descr, tech-c, admin-c, remarks, notify, mnt-by, changed and source attributes show up in all RPSL classes π Their syntax, semantics, and whether they're mandatory, optional, multi-valued, or single-valued are the same across every RPSL class. The only exception is admin-c, which is mandatory for the aut-num class. We won't go over them again in the other sections, so consider this your one-and-only intro π
3.2 person Class
The person class describes information about people π§ It doesn't describe routing policy, but we still cover it briefly here because lots of policy objects reference person objects. It was first described in [15].
The attributes of the person class are shown in Figure 3. The person attribute is the person's full name. The phone and fax-no attributes follow this syntax:
phone: +<country-code> <city> <subscriber> [ext. <extension>]
E.g.:
phone: +31 20 12334676
Attribute Value Type
person <free-form> mandatory, single-valued
nic-hdl <nic-handle> mandatory, single-valued, class key
address <free-form> mandatory, multi-valued
phone see description in text mandatory, multi-valued
fax-no same as phone optional, multi-valued
e-mail <email-address> mandatory, multi-valued
Figure 3: person Class Attributes
phone: +44 123 987654 ext. 4711
Figure 4 shows an example person object π
person: Daniel Karrenberg
address: RIPE Network Coordination Centre (NCC)
address: Singel 258
address: NL-1016 AB Amsterdam
address: Netherlands
phone: +31 20 535 4444
fax-no: +31 20 535 4445
e-mail: Daniel.Karrenberg@ripe.net
nic-hdl: DK58
changed: Daniel.Karrenberg@ripe.net 19970616
source: RIPE
Figure 4: An example person object.
3.3 role Class
The role class is kind of like the person object, except instead of describing a human being, it describes a role that one or more humans perform π Think help desks, network monitoring centers, system administrators, and so on. Role objects are super useful because the person doing a role often changes, but the role itself sticks around π§
The attributes of the role class are shown in Figure 5. The nic-hdl attributes of the person and role classes share the same name space, so they can't clash π The trouble attribute of a role object can hold extra contact info for when a problem comes up in any object that references this role object π Figure 6 shows an example role object.
Attribute Value Type
role <free-form> mandatory, single-valued
nic-hdl <nic-handle> mandatory, single-valued,
class key
trouble <free-form> optional, multi-valued
address <free-form> mandatory, multi-valued
phone see description in text mandatory, multi-valued
fax-no same as phone optional, multi-valued
e-mail <email-address> mandatory, multi-valued
Figure 5: role Class Attributes
role: RIPE NCC Operations
trouble:
address: Singel 258
address: 1016 AB Amsterdam
address: The Netherlands
phone: +31 20 535 4444
fax-no: +31 20 545 4445
e-mail: ops@ripe.net
admin-c: CO19-RIPE
tech-c: RW488-RIPE
tech-c: JLSD1-RIPE
nic-hdl: OPS4-RIPE
notify: ops@ripe.net
changed: roderik@ripe.net 19970926
source: RIPE
Figure 6: An example role object.
4 route Class β¨
Each interAS route (also called an interdomain route) that an AS originates gets specified using a route object π The attributes of the route class are shown in Figure 7. The route attribute is the address prefix of the route, and the origin attribute is the AS number of the AS that originates the route into the interAS routing system. The route and origin pair is the class key, so that combo is the unique ID π
Figure 8 shows examples of four route objects. We skip contact attributes like admin-c and tech-c to keep it short π Notice that the last two route objects have the same address prefix, 128.8.0.0/16. They're still different route objects because different ASes originate them, meaning they have different keys. Iconic, right? π¦
Attribute Value Type
route <address-prefix> mandatory, single-valued,
class key
origin <as-number> mandatory, single-valued,
class key
member-of list of <route-set-names> optional, multi-valued
see Section 5
inject see Section 8 optional, multi-valued
components see Section 8 optional, single-valued
aggr-bndry see Section 8 optional, single-valued
aggr-mtd see Section 8 optional, single-valued
export-comps see Section 8 optional, single-valued
holes see Section 8 optional, multi-valued
Figure 7: route Class Attributes
route: 128.9.0.0/16
origin: AS226
route: 128.99.0.0/16
origin: AS226
route: 128.8.0.0/16
origin: AS1
route: 128.8.0.0/16
origin: AS2
Figure 8: Route Objects
5 Set Classes π§Ί
To write policies, it's often handy to define sets of objects π For that we define the as-set, route-set, rtr-set, filter-set, and peering-set classes. These classes define a named set. The members of a set can be listed directly in the set's definition, pulled in indirectly by having member objects refer to the set's name, or both. Mix and match, bestie π
A set's name is an rpsl word with some rules: every as-set name starts with the prefix "as-", every route-set name starts with "rs-", every rtr-set name starts with "rtrs-", every filter-set name starts with "fltr-", and every peering-set name starts with "prng-". For example, as-foo is a valid as-set name β
Set names can also be hierarchical πͺ A hierarchical set name is a sequence of set names and AS numbers separated by colons ":". At least one component of that name has to be an actual set name, meaning it starts with one of the prefixes above. All the set name components of a hierarchical name have to be the same type. For example, these names are valid: AS1:AS-CUSTOMERS, AS1:RS-EXPORT:AS2, RS-EXCEPTIONS:RS-BOGUS.
The whole point of a hierarchical set name is to split up the set name space so that the maintainers of set X1 control everything underneath it, i.e. X1:...:Xn-1 π° So a set object named X1:...:Xn-1:Xn can only be created by the maintainer of the object named X1:...:Xn-1. Put simply, only the maintainer of AS1 can create a set named AS1:AS-FOO, and only the maintainer of AS1:AS-FOO can create a set named AS1:AS-FOO:AS-BAR. For the details, check out the RPS Security Document [20] π It's giving organized, and I'm obsessed.
5.1 as-set Class β¨
Okay bestie, the as-set class is where we group ASes together π¦ Its attributes are shown in Figure 9. The as-set attribute is the name of the set, and it's an RPSL name that starts with as- π The members attribute is the list of who's in the squad: AS numbers or other as-set names π«Ά
Attribute Value Type
as-set <object-name> mandatory, single-valued,
class key
members list of <as-numbers> or optional, multi-valued
<as-set-names>
mbrs-by-ref list of <mntner-names> optional, multi-valued
Figure 9: as-set Class Attributes
Figure 10 shows two as-set objects, and they're giving main character energy π The set as-foo has two ASes, AS1 and AS2. The set as-bar has everything in as-foo plus AS3, so it contains AS1, AS2, AS3 πΈ And as-empty? Literally no members π
as-set: as-foo as-set: as-bar as-set: as-empty
members: AS1, AS2 members: AS3, as-foo
Figure 10: as-set objects.
Now the mbrs-by-ref attribute is a list of maintainer names or the keyword ANY π₯ If you use it, the AS set also picks up ASes whose aut-num objects are registered by one of those maintainers and whose member-of attribute points to this AS set. If the value is ANY, any AS object that refers to the AS set is a member of the set β¨ And if mbrs-by-ref is missing entirely? Only the ASes listed in members get in π
as-set: as-foo
members: AS1, AS2
mbrs-by-ref: MNTR-ME
aut-num: AS3 aut-num: AS4
member-of: as-foo member-of: as-foo
mnt-by: MNTR-ME mnt-by: MNTR-OTHER
Figure 11: as-set objects.
Figure 11 is the example that uses mbrs-by-ref, and it's so good π The set as-foo contains AS1, AS2 and AS3. AS4 is NOT in as-foo even though its aut-num object references as-foo, because MNTR-OTHER isn't listed in as-foo's mbrs-by-ref attribute. Not me being picky about who gets in π
5.2 route-set Class π¦
The route-set class works just like the as-set class, except it's for routes π Its attributes are in Figure 12. The route-set attribute is the name, and it's an RPSL name that starts with rs-. The members attribute lists the members, and those can be address prefixes or other route-set names. Quick heads up: the route-set class is a set of route prefixes, NOT a set of RPSL route objects π
Attribute Value Type
route-set <object-name> mandatory,
single-valued,
class key
members list of <address-prefix-range> or optional, multi-valued
<route-set-name> or
<route-set-name><range-operator>
mbrs-by-ref list of <mntner-names> optional, multi-valued
Figure 12: route-set Class Attributes
Figure 13 has some example route-set objects. The set rs-foo has two address prefixes, 128.9.0.0/16 and 128.9.0.0/24. The set rs-bar has everything in rs-foo plus 128.7.0.0/16 π§
route-set: rs-foo
members: 128.9.0.0/16, 128.9.0.0/24
route-set: rs-bar
members: 128.7.0.0/16, rs-foo
Figure 13: route-set Objects
An address prefix or a route-set name in a members attribute can optionally be followed by a range operator, and this part is seriously fun π Check out this one:
route-set: rs-bar
members: 5.0.0.0/8^+, 30.0.0.0/8^24-32, rs-foo^+
That set contains all the more specifics of 5.0.0.0/8, including 5.0.0.0/8 itself. It also contains all the more specifics of 30.0.0.0/8 that are of length 24 to 32, like 30.9.9.96/28, plus all the more specifics of the address prefixes in route set rs-foo β¨
The mbrs-by-ref attribute works the same way as before: a list of maintainer names or the keyword ANY π If you use it, the route set also includes address prefixes whose route objects are registered by one of those maintainers and whose member-of attribute refers to this route set name. If the value is ANY, any route object that refers to the route set name is a member. If mbrs-by-ref is missing, only the address prefixes listed in members are members of the set π«Ά
route-set: rs-foo
mbrs-by-ref: MNTR-ME, MNTR-YOU
route-set: rs-bar
members: 128.7.0.0/16
mbrs-by-ref: MNTR-YOU
route: 128.9.0.0/16
origin: AS1
member-of: rs-foo
mnt-by: MNTR-ME
route: 128.8.0.0/16
origin: AS2
member-of: rs-foo, rs-bar
mnt-by: MNTR-YOU
Figure 14: route-set objects.
Figure 14 is the example that uses mbrs-by-ref, and I'm obsessed π The set rs-foo has two address prefixes, 128.8.0.0/16 and 128.9.0.0/16, because both of those route objects point to rs-foo in their member-of attribute. The set rs-bar has 128.7.0.0/16 and 128.8.0.0/16. The route 128.7.0.0/16 is listed right in the members attribute of rs-bar, and the route object for 128.8.0.0/16 points to rs-bar in its member-of attribute π
Also, if an address prefix is listed in the members attribute of a route set, it IS a member of that route set. The route object for that prefix doesn't need a member-of attribute pointing back at the set name. The member-of attribute of the route class is just an extra way to add members indirectly π
5.3 Predefined Set Objects π
When a route set is expected (like in the members attribute of the route-set class), an AS number ASx defines the set of routes originated by ASx, and an as-set AS-X defines the set of routes originated by the ASes in AS-X π¦ A route p counts as originated by ASx if there's a route object for p with ASx as the value of its origin attribute. For example, in Figure 15, the route set rs-special contains 128.9.0.0/16, the routes of AS1 and AS2, and the routes of the ASes in the AS set AS-FOO π
route-set: rs-special
members: 128.9.0.0/16, AS1, AS2, AS-FOO
Figure 15: Use of AS numbers and AS sets in route sets.
Last but not least, the set rs-any contains all routes registered in IRR, and the set as-any contains all ASes registered in IRR πΈ
5.4 Filters and filter-set Class β¨
okay bestie, filters are where the magic happens π¦ A filter-set object defines a set of routes that its filter matches. The filter-set attribute holds the name, and it's an RPSL name that starts with "fltr-" π
Figure 16 shows the attributes:
Attribute Value Type
filter-set <object-name> mandatory, single-valued, class key
filter <filter> mandatory, single-valued
Figure 16: filter Class Attributes
And Figure 17 has two examples:
filter-set: fltr-foo
filter: { 5.0.0.0/8, 6.0.0.0/8 }
filter-set: fltr-bar
filter: (AS1 or fltr-foo) and <AS2>
Figure 17: filter-set objects.
The filter attribute is the set's policy filter π₯ A policy filter is a logical expression. When you apply it to a set of routes, it returns a subset of them, and we say the policy filter matches that subset. It can match routes using any BGP path attribute, like the destination address prefix (or NLRI), AS-path, or community attributes. so many options π
Policy filters can be composite using the operators AND, OR, and NOT. Here's what you can use to select a subset of routes:
ANY
The keyword ANY matches all routes π
Address-Prefix Set
This is an explicit list of address prefixes wrapped in braces { and }. The policy filter matches the routes whose destination address-prefix is in the set. For example:
{ 0.0.0.0/0 }
{ 128.9.0.0/16, 128.8.0.0/16, 128.7.128.0/17, 5.0.0.0/8 }
{ }
An address prefix can optionally be followed by a range operator (i.e.
{ 5.0.0.0/8^+, 128.9.0.0/16^-, 30.0.0.0/8^16, 30.0.0.0/8^24-32 }
This contains all the more specifics of 5.0.0.0/8 including 5.0.0.0/8, all the more specifics of 128.9.0.0/16 excluding 128.9.0.0/16, all the more specifics of 30.0.0.0/8 which are of length 16 (like 30.9.0.0/16), and all the more specifics of 30.0.0.0/8 which are of length 24 to 32 (like 30.9.9.96/28) π§
Route Set Name
A route set name matches the set of routes that are members of the set. It can be the name of a route-set object, an AS number, or the name of an as-set object. AS numbers and as-set names implicitly define route sets, so check out Section 5.3 for more on that π For example:
aut-num: AS1
import: from AS2 accept AS2
import: from AS2 accept AS-FOO
import: from AS2 accept RS-FOO
The keyword PeerAS can be used instead of the AS number of the peer AS. It's super useful when the peering is specified using an AS expression π«Ά For example:
as-set: AS-FOO
members: AS2, AS3
aut-num: AS1
import: from AS-FOO accept PeerAS
is the same as:
aut-num: AS1
import: from AS2 accept AS2
import: from AS3 accept AS3
A route set name can also be followed by one of the operators ^- or ^+. For example, { 5.0.0.0/8, 6.0.0.0/8 }^+ equals { 5.0.0.0/8^+, 6.0.0.0/8^+ }, and AS1^- equals all the exclusive more specifics of routes originated by AS1 π
AS Path Regular Expressions
An AS-path regular expression can be used as a policy filter by enclosing the expression in < and >. An AS-path policy filter matches the set of routes that traverse a sequence of ASes matched by the AS-path regular expression. A router can check this using the AS_PATH attribute in the Border Gateway Protocol [19], or the RD_PATH attribute in the Inter-Domain Routing Protocol [18] πΈ
AS-path regular expressions are POSIX compliant regular expressions over the alphabet of AS numbers. The regular expression constructs are:
ASN: where ASN is an AS number. It matches the AS-path that is of length 1 and contains that AS number (e.g. the AS-path regular expressionAS1matches the AS-path "1"). The keywordPeerAScan be used instead of the AS number of the peer AS.AS-set: where AS-set is an AS set name. It matches the AS-paths that are matched by one of the ASes in the AS-set..: matches the AS-paths matched by any AS number.[...]: is an AS number set. It matches the AS-paths matched by the AS numbers listed between the brackets. The AS numbers in the set are separated by white space characters. If a-is used between two AS numbers in this set, all AS numbers between the two are included in the set. If an as-set name is listed, all AS numbers in the as-set are included.[^...]: is a complemented AS number set. It matches any AS-path that is not matched by the AS numbers in the set.^: matches the empty string at the beginning of an AS-path.$: matches the empty string at the end of an AS-path.
Next up are the regular expression operators, listed in decreasing order of evaluation. These operators are left associative, meaning they're performed left to right π
- Unary postfix operators
*+?{m}{m,n}{m,}: For a regular expression A,A*matches zero or more occurrences of A,A+matches one or more occurrences of A,A?matches zero or one occurrence of A,A{m}matches m occurrences of A,A{m,n}matches m to n occurrences of A, andA{m,}matches m or more occurrences of A. For example,[AS1 AS2]{2}matches AS1 AS1, AS1 AS2, AS2 AS1, and AS2 AS2. - Unary postfix operators
~*~+~{m}~{m,n}~{m,}: These have similar functionality to the operators above, but all occurrences of the regular expression have to match the same pattern. For example,[AS1 AS2]~{2}matches AS1 AS1 and AS2 AS2, but it does not match AS1 AS2 or AS2 AS1 π - Binary catenation operator: This is an implicit operator that exists between two regular expressions A and B when no other explicit operator is specified. The resulting expression
A Bmatches an AS-path if A matches some prefix of the AS-path and B matches the rest of it. - Binary alternative (or) operator
|: For regular expressions A and B,A | Bmatches any AS-path that is matched by A or B.
Parentheses can be used to override the default order of evaluation. White spaces can be used to increase readability β¨
Here are some examples of AS-path filters:
<AS3>
<^AS1>
<AS2$>
<^AS1 AS2 AS3$>
<^AS1 .* AS2$>
The first example matches any route whose AS-path contains AS3. The second matches routes whose AS-path starts with AS1. The third matches routes whose AS-path ends with AS2. The fourth matches routes whose AS-path is exactly "1 2 3". And the fifth matches routes whose AS-path starts with AS1 and ends in AS2, with any number of AS numbers in between π
Composite Policy Filters
The following operators (in decreasing order of evaluation) can be used to form composite policy filters π
- NOT: Given a policy filter x,
NOT xmatches the set of routes that are not matched by x. It's the negation of policy filter x. - AND: Given two policy filters x and y,
x AND ymatches the intersection of the routes matched by x and the routes matched by y. - OR: Given two policy filters x and y,
x OR ymatches the union of the routes matched by x and the routes matched by y.
An OR operator can be implicit, so x y is equivalent to x OR y π
E.g.
NOT {128.9.0.0/16, 128.8.0.0/16}
AS226 AS227 OR AS228
AS226 AND NOT {128.9.0.0/16}
AS226 AND {0.0.0.0/0^0-18}
The first example matches any route except 128.9.0.0/16 and 128.8.0.0/16. The second matches the routes of AS226, AS227, and AS228. The third matches the routes of AS226 except 128.9.0.0/16. The fourth matches the routes of AS226 whose length is not longer than 18 π
Routing Policy Attributes
Policy filters can also use the values of other attributes for comparison. The attributes whose values can be used in policy filters are specified in the RPSL dictionary. Please refer to Section 7 for details. Here's an example using the BGP community attribute:
aut-num: AS1
export: to AS2 announce AS1 AND NOT community(NO_EXPORT)
Filters using the routing policy attributes defined in the dictionary are evaluated before the AND, OR, and NOT operators are evaluated π¦
Filter Set Name
A filter set name matches the set of routes that are matched by its filter attribute. The filter attribute of a filter set can recursively refer to other filter set names. For example, in Figure 17, fltr-foo matches { 5.0.0.0/8, 6.0.0.0/8 }, and fltr-bar matches AS1'S routes or { 5.0.0.0/8, 6.0.0.0/8 } if their AS path contained AS2 π
5.5 rtr-set Class
The attributes of the rtr-set class are shown in Figure 18. The rtr-set attribute defines the name of the set. It's an RPSL name that starts with "rtrs-" πΈ The members attribute lists the members of the set. It's a list of inet-rtr names, ipv4_addresses, or other rtr-set names π«Ά
Attribute Value Type
rtr-set <object-name> mandatory, single-valued,
class key
members list of <inet-rtr-names> or optional, multi-valued
<rtr-set-names>
or <ipv4_addresses>
mbrs-by-ref list of <mntner-names> optional, multi-valued
Figure 18: rtr-set Class Attributes
Figure 19 presents two rtr-set objects. The set rtrs-foo contains two routers, rtr1.isp.net and rtr2.isp.net. The set rtrs-bar contains the members of the set rtrs-foo plus rtr3.isp.net, so it contains rtr1.isp.net, rtr2.isp.net, and rtr3.isp.net π
rtr-set: rtrs-foo rtr-set: rtrs-bar
members: rtr1.isp.net, rtr2.isp.net members: rtr3.isp.net, rtrs-foo
Figure 19: rtr-set objects.
The mbrs-by-ref attribute is a list of maintainer names or the keyword ANY. If this attribute is used, the router set also includes routers whose inet-rtr objects are registered by one of these maintainers and whose member-of attribute refers to the name of this router set. If the value of a mbrs-by-ref attribute is ANY, any inet-rtr object referring to the router set is a member of the set. If the mbrs-by-ref attribute is missing, only the routers listed in the members attribute are members of the set π§
rtr-set: rtrs-foo
members: rtr1.isp.net, rtr2.isp.net
mbrs-by-ref: MNTR-ME
inet-rtr: rtr3.isp.net
local-as: as1
ifaddr: 1.1.1.1 masklen 30
member-of: rtrs-foo
mnt-by: MNTR-ME
Figure 20: rtr-set objects.
Figure 20 presents an example rtr-set object that uses the mbrs-by-ref attribute. The set rtrs-foo contains rtr1.isp.net, rtr2.isp.net, and rtr3.isp.net π
5.6 Peerings and peering-set Class π«Ά
okay so this is where peering-sets come in and it's giving organization π Figure 21 shows the attributes. A peering-set object bundles up a bunch of peerings under one name, and that name lives in the peering-set attribute. It's an RPSL name that starts with "prng-" π
Attribute Value Type
peering-set <object-name> mandatory, single-valued, class key
peering <peering> mandatory, multi-valued
Figure 21: filter Class Attributes
The peering attribute defines a peering that can be used for importing or
---------------------- ----------------------
| 7.7.7.1 |-------| |-------| 7.7.7.2 |
| | ======== | |
| AS1 | EX1 |-------| 7.7.7.3 AS2 |
| | | |
| 9.9.9.1 |------ ------| 9.9.9.2 |
---------------------- | | ----------------------
===========
| EX2
---------------------- |
| 9.9.9.3 |---------
| |
| AS3 |
----------------------
Figure 22: Example topology consisting of three ASes, AS1, AS2, and
AS3; two exchange points, EX1 and EX2; and six routers.
exporting routes.
okay, picture this topology π§ we're using Figure 22 for every peering example. There are three ASes (AS1, AS2, and AS3), two exchange points (EX1 and EX2), and six routers. Routers connected to the same exchange point peer with each other and swap routing info. So 7.7.7.1, 7.7.7.2 and 7.7.7.3 all peer with each other, and 9.9.9.1, 9.9.9.2 and 9.9.9.3 peer with each other πΈ
The syntax of a peering specification is:
<as-expression> [<router-expression-1>] [at <router-expression-2>]
| <peering-set-name>
where <as-expression> is an expression over AS numbers and AS sets using the operators AND, OR, and EXCEPT. <router-expression-1> and <router-expression-2> are expressions over router IP addresses, inet-rtr names, and rtr-set names, also using AND, OR, and EXCEPT. The binary EXCEPT operator is set subtraction and has the same precedence as AND (it's semantically the same as an "AND NOT" combo). So (AS1 OR AS2) EXCEPT AS2 equals AS1 π
This form identifies all the peerings between any local router in <router-expression-2> and any of their peer routers in <router-expression-1> within the ASes in <as-expression>. If <router-expression-2> isn't specified, it defaults to all routers of the local AS that peer with ASes in <as-expression>. If <router-expression-1> isn't specified, it defaults to all routers of the peer ASes in <as-expression> that peer with the local AS β¨
If a <peering-set-name> is used, the peerings get listed in the matching peering-set object. Note that peering-set objects can be recursive π
Okay so there are a LOT of special forms of this general peering specification π The examples below show the most common ones, using the import attribute of the aut-num class. In the first one, 7.7.7.1 imports 128.9.0.0/16 from 7.7.7.2.
(1) aut-num: AS1
import: from AS2 7.7.7.2 at 7.7.7.1 accept { 128.9.0.0/16 }
In this one, 7.7.7.1 imports 128.9.0.0/16 from 7.7.7.2 and 7.7.7.3.
(2) aut-num: AS1
import: from AS2 at 7.7.7.1 accept { 128.9.0.0/16 }
In this one, 7.7.7.1 imports 128.9.0.0/16 from 7.7.7.2 and 7.7.7.3, and 9.9.9.1 imports 128.9.0.0/16 from 9.9.9.2.
(3) aut-num: AS1
import: from AS2 accept { 128.9.0.0/16 }
In this one, 9.9.9.1 imports 128.9.0.0/16 from 9.9.9.2 and 9.9.9.3.
(4) as-set: AS-FOO
members: AS2, AS3
aut-num: AS1
import: from AS-FOO at 9.9.9.1 accept { 128.9.0.0/16 }
In this one, 9.9.9.1 imports 128.9.0.0/16 from 9.9.9.2 and 9.9.9.3, and 7.7.7.1 imports 128.9.0.0/16 from 7.7.7.2 and 7.7.7.3.
(5) aut-num: AS1
import: from AS-FOO accept { 128.9.0.0/16 }
In this one, AS1 imports 128.9.0.0/16 from AS3 at router 9.9.9.1.
(6) aut-num: AS1
import: from AS-FOO and not AS2 at not 7.7.7.1
accept { 128.9.0.0/16 }
This is because "AS-FOO and not AS2" equals AS3 and "not 7.7.7.1" equals 9.9.9.1 π
In this one, 9.9.9.1 imports 128.9.0.0/16 from 9.9.9.2 and 9.9.9.3.
(7) peering-set: prng-bar
peering: AS1 at 9.9.9.1
peering-set: prng-foo
peering: prng-bar
peering: AS2 at 9.9.9.1
aut-num: AS1
import: from prng-foo accept { 128.9.0.0/16 }
6 aut-num Class π¦
okay so routing policies are specified using the aut-num class π The aut-num attribute holds the AS number of the AS that the object describes. The as-name attribute is a symbolic name (in RPSL name syntax) for the AS. The import, export and default routing policies of the AS are set with the import, export and default attributes, respectively β¨ Figure 23 shows all the attributes.
Attribute Value Type
aut-num <as-number> mandatory, single-valued, class key
as-name <object-name> mandatory, single-valued
member-of list of <as-set-names> optional, multi-valued
import see Section 6.1 optional, multi valued
export see Section 6.2 optional, multi valued
default see Section 6.5 optional, multi valued
Figure 23: aut-num Class Attributes
6.1 import Attribute: Import Policy Specification
In RPSL, an import policy gets split into import policy expressions πΈ Each import policy expression is written with an import attribute. The import attribute has the following syntax (we'll extend it later in Sections 6.3 and 6.6):
import: from <peering-1> [action <action-1>]
. . .
from <peering-N> [action <action-N>]
accept <filter>
The action specification is optional. Here's how an import attribute works: the set of routes matched by <filter> gets imported from all the peers in <peerings>, and while importing routes at <peering-M>, <action-M> gets executed π
E.g.
aut-num: AS1
import: from AS2 action pref = 1; accept { 128.9.0.0/16 }
In this example, the route 128.9.0.0/16 is accepted from AS2 with preference 1. We already covered how peerings (see Section 5.6) and filters (see Section 5.4) are specified. Next up, actions π
6.1.1 Action Specification
Policy actions in RPSL either set or modify route attributes, like giving a route a preference, adding a BGP community to the BGP community path attribute, or setting the MULTI-EXIT-DISCRIMINATOR attribute. Policy actions can also tell routers to do special operations, like route flap damping π§
The routing policy attributes whose values can be changed in policy actions are listed in the RPSL dictionary. Check out Section 7 for a list of them. Each action in RPSL ends with a semicolon (';'). You can make composite policy actions by listing them one after another. In a composite policy action, the actions run left to right. For example:
aut-num: AS1
import: from AS2
action pref = 10; med = 0; community.append(10250, 3561:10);
accept { 128.9.0.0/16 }
This sets pref to 10, med to 0, and then appends 10250 and 3561:10 to the BGP community path attribute π The pref attribute is the inverse of the local-pref attribute (i.e. local-pref == 65535 - pref). A route with a local-pref attribute is always preferred over a route without one β¨
aut-num: AS1
import: from AS2 action pref = 1;
from AS3 action pref = 2;
accept AS4
The example above says AS4's routes get accepted from AS2 with preference 1, and from AS3 with preference 2. Routes with lower integer preference values are preferred over routes with higher ones π
aut-num: AS1
import: from AS2 7.7.7.2 at 7.7.7.1 action pref = 1;
from AS2 action pref = 2;
accept AS4
The example above says AS4's routes are accepted from AS2 on the peering 7.7.7.1-7.7.7.2 with preference 1, and on any other peering with AS2 with preference 2 π
6.2 export Attribute: Export Policy Specification
Similarly, an export policy expression gets written with an export attribute. The export attribute has the following syntax:
export: to <peering-1> [action <action-1>]
. . .
to <peering-N> [action <action-N>]
announce <filter>
The action specification is optional. The export attribute works like this: the set of routes matched by <filter> gets exported to all the peers listed in <peerings>, and while exporting routes at <peering-M>, <action-M> gets executed π«Ά
E.g.
aut-num: AS1
export: to AS2 action med = 5; community .= { 70 };
announce AS4
In this example, AS4's routes are announced to AS2 with the med attribute set to 5, and community 70 added to the community list π
Example:
aut-num: AS1
export: to AS-FOO announce ANY
In this example, AS1 announces all of its routes to the ASes in the set AS-FOO π
6.3 Other Routing Protocols, Multi-Protocol Routing Protocols, and Injecting Routes Between Protocols β¨
okay so here's the fuller syntax for import and export π¦
import: [protocol <protocol-1>] [into <protocol-2>]
from <peering-1> [action <action-1>]
. . .
from <peering-N> [action <action-N>]
accept <filter>
export: [protocol <protocol-1>] [into <protocol-2>]
to <peering-1> [action <action-1>]
. . .
to <peering-N> [action <action-N>]
announce <filter>
the optional protocol bits are what let you write policies for other routing protocols, inject routes from one protocol into another, or do multi-protocol routing policies π
The valid protocol names live in the dictionary. <protocol-1> is the protocol whose routes are being exchanged, and <protocol-2> is the protocol that's receiving them. Both default to the Internet Exterior Gateway Protocol, which is BGP right now πΈ
ex 1: dumping every interAS route into RIP π
aut-num: AS1
import: from AS2 accept AS2
export: protocol BGP4 into RIP
to AS1 announce ANY
ex 2: AS1 takes AS2's routes plus any more-specifics of them, but doesn't push those extra more-specifics into OSPF π§
aut-num: AS1
import: from AS2 accept AS2^+
export: protocol BGP4 into OSPF
to AS1 announce AS2
ex 3: AS1 pushes its static routes (anything in the set AS1:RS-STATIC-ROUTES) into the interAS protocol and tacks AS1 on to their AS paths twice π₯
aut-num: AS1
import: protocol STATIC into BGP4
from AS1 action aspath.prepend(AS1, AS1);
accept AS1:RS-STATIC-ROUTES
ex 4: AS1 pulls a different set of unicast routes from AS2 for multicast reverse path forwarding π«Ά
aut-num: AS1
import: from AS2 accept AS2
import: protocol IDMR
from AS2 accept AS2:RS-RPF-ROUTES
6.4 Ambiguity Resolution
so sometimes the same peering gets covered by more than one peering specification in a policy π this is not an error, but it's definitely not the vibe Here's an example:
aut-num: AS1
import: from AS2 7.7.7.2 at 7.7.7.1 action pref = 2;
from AS2 7.7.7.2 at 7.7.7.1 action pref = 1;
accept AS4
To break the tie, the action from the first peering specification is the one that gets used. So the routes get accepted with preference 2. We call this the specification-order rule π
Now check this one:
aut-num: AS1
import: from AS2 action pref = 2;
from AS2 7.7.7.2 at 7.7.7.1 action pref = 1; dpa = 5;
accept AS4
Both peering specs cover the peering 7.7.7.1-7.7.7.2, but the second one is more specific about it. The specification-order rule still applies, so only pref = 2 runs. The second peering-action pair never does anything, because the first one always covers it first π If you actually wanted preference 1 on that one specific peering and preference 2 everywhere else, you'd write it like this:
aut-num: AS1
import: from AS2 7.7.7.2 at 7.7.7.1 action pref = 1; dpa = 5;
from AS2 action pref = 2;
accept AS4
It's also possible for more than one policy expression to cover the same routes on the same peering π
aut-num: AS1
import: from AS2 action pref = 2; accept AS4
import: from AS2 action pref = 1; accept AS4
The specification-order rule still wins here too. AS4's routes come in from AS2 with preference 2. If the filters overlap but aren't exactly the same:
aut-num: AS1
import: from AS2 action pref = 2; accept AS4
import: from AS2 action pref = 1; accept AS4 OR AS5
then AS4's routes are accepted from AS2 with preference 2, and AS5's routes are also accepted, just with preference 1 β¨
Next up is the general specification-order rule, for the RPSL implementors out there π€ Say you have two policy expressions:
aut-num: AS1
import: from peerings-1 action action-1 accept filter-1
import: from peerings-2 action action-2 accept filter-2
Those are equivalent to these three expressions, which have no ambiguity left:
aut-num: AS1
import: from peerings-1 action action-1 accept filter-1
import: from peerings-3 action action-2 accept filter-2 AND NOT filter-1
import: from peerings-4 action action-2 accept filter-2
where peerings-3 are the peerings covered by both peerings-1 and peerings-2, and peerings-4 are the ones covered by peerings-2 but not by peerings-1. (filter-2 AND NOT filter-1 matches the routes that filter-2 matches but filter-1 doesn't.) π§
Example time:
aut-num: AS1
import: from AS2 7.7.7.2 at 7.7.7.1
action pref = 2;
accept {128.9.0.0/16}
import: from AS2
action pref = 1;
accept {128.9.0.0/16, 75.0.0.0/8}
Let's say there are two peerings with AS2: 7.7.7.1-7.7.7.2 and 9.9.9.1-9.9.9.2. Both policy expressions cover 7.7.7.1-7.7.7.2. On that peering, 128.9.0.0/16 is accepted with preference 2, and 75.0.0.0/8 is accepted with preference 1. The peering 9.9.9.1-9.9.9.2 is only covered by the second policy expression, so both 128.9.0.0/16 and 75.0.0.0/8 get accepted there with preference 1 π¦
Last thing for this bit: the same ambiguity resolution rules also apply to export and default policy expressions π
6.5 default Attribute: Default Policy Specification
default routing policies get set with the default attribute πΈ It looks like this:
default: to <peering> [action <action>] [networks <filter>]
The <action> and <filter> parts are both optional. Here's what they mean. The <peering> tells you which AS (and which router, if you include one) you're defaulting to. The <action>, if it's there, describes things about the default, like a relative preference when you've got multiple defaults. The <filter>, if it's there, is a policy filter. A router only uses the default policy if it got the routes matched by <filter> from that peer π
ex: AS1 defaults to AS2 for routing π§
aut-num: AS1
default: to AS2
ex: router 7.7.7.1 in AS1 defaults to router 7.7.7.2 in AS2 π
aut-num: AS1
default: to AS2 7.7.7.2 at 7.7.7.1
ex: AS1 defaults to both AS2 and AS3, but likes AS2 more π
aut-num: AS1
default: to AS2 action pref = 1;
default: to AS3 action pref = 2;
ex: AS1 defaults to AS2 and uses 128.9.0.0/16 as the default network π
aut-num: AS1
default: to AS2 networks { 128.9.0.0/16 }
6.6 Structured Policy Specification
okay so import and export policies can be structured π§ heads up though: structured policies are really only recommended for advanced RPSL users, so if that's not you, feel free to skip this whole section, no shade π«Ά
The syntax for a structured policy is below:
<import-factor> ::= from <peering-1> [action <action-1>]
. . .
from <peering-N> [action <action-N>]
accept <filter>;
<import-term> ::= <import-factor> |
LEFT-BRACE
<import-factor>
. . .
<import-factor>
RIGHT-BRACE
<import-expression> ::= <import-term> |
<import-term> EXCEPT <import-expression> |
<import-term> REFINE <import-expression>
import: [protocol <protocol1>] [into <protocol2>]
<import-expression>
Please note the semicolon at the end of an <import-factor>. When a policy isn't structured (like every example in the other sections), that semicolon is optional. The syntax and semantics of an <import-factor> were already defined in Section 6.1 π
An <import-term> is either a bunch of <import-factor>s wrapped in matching braces ({ and }), or just one single <import-factor>. The semantics of an <import-term> are the union of its <import-factor>s, using the specification-order rule. An <import-expression> is either one <import-term>, or an <import-term> followed by either the keyword "except" or the keyword "refine", followed by another <import-expression>. Nesting is allowed, so you can have exceptions to exceptions, refinements to refinements, or even refinements to exceptions, and so on π
Here's how the except operator works. The result of an except operation is another <import-term>. The resulting policy set has the policies from the right-hand side, but their filters get changed so they only include routes that the left-hand side also matches. The left-hand side's policies get added afterwards, and their filters get changed to exclude the routes the right-hand side matches. Filters get modified in this process, but actions are copied over word for word. With multiple levels of nesting, the operations (both except and refine) get performed right to left π
Let's look at this example:
import: from AS1 action pref = 1; accept as-foo;
except {
from AS2 action pref = 2; accept AS226;
except {
from AS3 action pref = 3; accept {128.9.0.0/16};
}
}
Here, 128.9.0.0/16 is originated by AS226, and AS226 is a member of the as-set as-foo. So 128.9.0.0/16 gets accepted from AS3. Any other route (not 128.9.0.0/16) originated by AS226 gets accepted from AS2. And any other ASes' routes in as-foo get accepted from AS1 π
We can get to the same answer using the algebra from above. Start with the inner exception specification:
from AS2 action pref = 2; accept AS226;
except {
from AS3 action pref = 3; accept {128.9.0.0/16};
}
is equivalent to:
{
from AS3 action pref = 3; accept AS226 AND {128.9.0.0/16};
from AS2 action pref = 2; accept AS226 AND NOT {128.9.0.0/16};
}
So the original expression is equivalent to:
import: from AS1 action pref = 1; accept as-foo;
except {
from AS3 action pref = 3; accept AS226 AND {128.9.0.0/16};
from AS2 action pref = 2; accept AS226 AND NOT {128.9.0.0/16};
}
which is equivalent to:
import: {
from AS3 action pref = 3;
accept as-foo AND AS226 AND {128.9.0.0/16};
from AS2 action pref = 2;
accept as-foo AND AS226 AND NOT {128.9.0.0/16};
from AS1 action pref = 1;
accept as-foo AND NOT
(AS226 AND NOT {128.9.0.0/16} OR AS226 AND {128.9.0.0/16});
}
Since AS226 is in as-foo and 128.9.0.0/16 is in AS226, it simplifies to:
import: {
from AS3 action pref = 3; accept {128.9.0.0/16};
from AS2 action pref = 2; accept AS226 AND NOT {128.9.0.0/16};
from AS1 action pref = 1; accept as-foo AND NOT AS226;
}
Okay so with the refine operator, the new set gets built by taking the cartesian product of both sides π
For every policy l on the left and every policy r on the right, the resulting policy's peerings are the peerings r and l have in common π€ Its filter is the intersection of l's filter and r's filter β¨, and its action is l's action followed by r's action. If there are no common peerings, or if the intersection of filters is empty, then no resulting policy gets generated π
Here's an example that makes it click:
import: { from AS-ANY action pref = 1; accept community(3560:10);
from AS-ANY action pref = 2; accept community(3560:20);
} refine {
from AS1 accept AS1;
from AS2 accept AS2;
from AS3 accept AS3;
}
So any route tagged with community 3560:10 gets a preference of 1 π and any route tagged with 3560:20 gets a preference of 2, no matter who it came from π¦ BUT, and this is the plot twist, only AS1's routes get imported from AS1, only AS2's routes get imported from AS2, and only AS3's routes get imported from AS3 π Nothing gets imported from any other AS, periodt. You can get to the exact same answer using the algebra above, so this example is equivalent to:
import: {
from AS1 action pref = 1; accept community(3560:10) AND AS1;
from AS1 action pref = 2; accept community(3560:20) AND AS1;
from AS2 action pref = 1; accept community(3560:10) AND AS2;
from AS2 action pref = 2; accept community(3560:20) AND AS2;
from AS3 action pref = 1; accept community(3560:10) AND AS3;
from AS3 action pref = 2; accept community(3560:20) AND AS3;
}
Quick note: the common peerings between "from AS1" and "from AS-ANY" are just the peerings in "from AS1" π We never formally define "common peerings", but you can totally work out the definition yourself from how peerings are defined (see Section 5.6) π§
Here's another one:
import: {
from AS-ANY action med = 0; accept {0.0.0.0/0^0-18};
} refine {
from AS1 at 7.7.7.1 action pref = 1; accept AS1;
from AS1 action pref = 2; accept AS1;
}
Only routes of length 0 to 18 get accepted, and the med value is set to 0 so med doesn't affect anything on any peering π On top of that, from AS1 only AS1's routes get imported, and AS1's routes imported at 7.7.7.1 are preferred over the other peerings π That's equivalent to:
import: {
from AS1 at 7.7.7.1 action med=0; pref=1; accept {0.0.0.0/0^0-
18} AND AS1;
from AS1 action med=0; pref=2; accept {0.0.0.0/0^0-
18} AND AS1;
}
And yes, the same syntax and semantics also apply to structured export policies π€ Just swap "from" for "to" and "accept" for "announce" π
7 dictionary Class β¨
The dictionary class is where RPSL gets its extensibility π Dictionary objects define routing policy attributes, types, and routing protocols. Routing policy attributes (we'll call them rp-attributes, no cap) can match real protocol attributes, like the BGP path attributes (such as community, dpa, and AS-path), or they can match router features (like BGP route flap damping). Whenever new protocols, new protocol attributes, or new router features show up, the dictionary object gets updated with the right rp-attribute and protocol definitions π¦
An rp-attribute is an abstract class, which means there's no data representation you can grab directly. You access it through access methods instead π For example, the rp-attribute for the BGP AS-path attribute is called aspath, and it has an access method called prepend that stuffs extra AS numbers into the AS-path attribute. Access methods can take arguments, and those arguments are strongly typed. Like, prepend takes AS numbers as its arguments, so it's not just vibes π
Once an rp-attribute is defined in the dictionary, you can use it to describe policy filters and actions π Policy analysis tools are required to fetch the dictionary object and recognize newly defined rp-attributes, types, and protocols. Tools are allowed to approximate policy analyses for rp-attributes they don't understand: a filter method may always match, and an action method may always perform a no-operation π Analysis tools can even download code to run the right operations, using mechanisms that sit outside the scope of RPSL.
Next up is the syntax and semantics of the dictionary class. This part isn't essential for understanding dictionary objects, but it's essential for creating one π§ So feel free to skip ahead to the RPSL Initial Dictionary subsection (Section 7.1) if you just want the good stuff π«Ά
The attributes of the dictionary class are shown in Figure 24. The dictionary attribute is the name of the dictionary object, and it follows the RPSL naming rules. There can be lots of dictionary objects, but there's always one well-known dictionary object called "RPSL", and every tool uses it by default π
Attribute Value Type
dictionary <object-name> mandatory, single-valued,
class key
rp-attribute see description in text optional, multi valued
typedef see description in text optional, multi valued
protocol see description in text optional, multi valued
Figure 24: dictionary Class Attributes
The rp-attribute attribute has the following syntax:
rp-attribute: <name>
<method-1>(<type-1-1>, ..., <type-1-N1> [, "..."])
...
<method-M>(<type-M-1>, ..., <type-M-NM> [, "..."])
Here, <name> is the name of the rp-attribute, and <method-i> is the name of an access method for it, taking Ni arguments where the j-th argument has type <type-i-j>. A method name is either an RPSL name or one of the operators listed in Figure 25. Every operator method except operator() and operator[] can only take one argument π
operator= operator==
operator<<= operator<
operator>>= operator>
operator+= operator>=
operator-= operator<=
operator*= operator!=
operator/= operator()
operator.= operator[]
Figure 25: Operators
An rp-attribute can have many methods, and some of them can even share a name as long as their arguments are different types π¦ If the argument list ends in "...", the method takes a variable number of arguments. In that case, the actual arguments after the Nth argument are of type <type-N> β¨
Arguments are strongly typed. A <type> in RPSL is a predefined type, a union type, a list type, or a dictionary defined type π The predefined types are listed in Figure 26.
integer[lower, upper] ipv4_address
real[lower, upper] address_prefix
enum[name, name, ...] address_prefix_range
string dns_name
boolean filter
rpsl_word as_set_name
free_text route_set_name
email rtr_set_name
as_number filter_set_name
peering_set_name
Figure 26: Predefined Types
The integer and real predefined types can be followed by a lower and an upper bound that specify the valid values of the argument. The range specification is optional πΈ We use the ANSI C language conventions for representing integer, real and string values. The enum type is followed by a list of RPSL names, which are the valid values of the type. The boolean type can be true or false. The as_number, ipv4_address, address_prefix and dns_name types are as in Section 2. The filter type is a policy filter as in Section 6, and its value is suggested to be enclosed in parentheses π
The syntax of a union type is:
union <type-1>, ... , <type-N>
Here <type-i> is an RPSL type. A union type is any one of the types <type-1> through <type-N>, which is analogous to unions in C[14] π
The syntax of a list type is:
list [<min_elems>:<max_elems>] of <type>
In this case the list elements are of <type>, and the list contains at least <min_elems> and at most <max_elems> elements. The size specification is optional. If it isn't specified, there's no restriction on how many list elements there can be β¨ A value of a list type is written as a sequence of elements separated by the character "," and enclosed by the characters "{" and "}".
The typedef attribute in the dictionary defines named types like this:
typedef: <name> <type>
Here <name> is a name for the type <type>. The typedef attribute is particularly useful when the type you're defining isn't a predefined type, like a list of unions or a list of lists π§
A protocol attribute of the dictionary class defines a protocol and a set of peering parameters for that protocol (these get used in the inet-rtr class in Section 9) π Its syntax is:
protocol: <name>
MANDATORY | OPTIONAL <parameter-1>(<type-1-1>,...,
<type-1-N1> [,"..."])
...
MANDATORY | OPTIONAL <parameter-M>(<type-M-1>,...,
<type-M-NM> [,"..."])
Here <name> is the name of the protocol, and MANDATORY and OPTIONAL are keywords. <parameter-i> is a peering parameter for this protocol, taking Ni arguments. The syntax and semantics of the arguments are the same as for rp-attribute. If the keyword MANDATORY is used, the parameter is mandatory and has to be specified for each peering of this protocol. If the keyword OPTIONAL is used, the parameter can be skipped π«Ά
7.1 Initial RPSL Dictionary and Example Policy Actions and Filters
Time for the starter pack π Here's the initial RPSL dictionary, with example policy actions and filters:
dictionary: RPSL
rp-attribute: # preference, smaller values represent higher preferences
pref
operator=(integer[0, 65535])
rp-attribute: # BGP multi_exit_discriminator attribute
med
# to set med to 10: med = 10;
# to set med to the IGP metric: med = igp_cost;
operator=(union integer[0, 65535], enum[igp_cost])
rp-attribute: # BGP destination preference attribute (dpa)
dpa
operator=(integer[0, 65535])
rp-attribute: # BGP aspath attribute
aspath
# prepends AS numbers from last to first order
prepend(as_number, ...)
typedef: # a community value in RPSL is either
# - a 4 byte integer (ok to use 3561:70 notation)
# - internet, no_export, no_advertise (see RFC-1997)
community_elm union
integer[1, 4294967295],
enum[internet, no_export, no_advertise],
typedef: # list of community values { 40, no_export, 3561:70 }
community_list list of community_elm
Pref, MED, and Route Stuff, Explained (Community Edition) π
rp-attribute: # BGP community attribute
community
# set to a list of communities
operator=(community_list)
# append community values
operator.=(community_list)
append(community_elm, ...)
# delete community values
delete(community_elm, ...)
# a filter: true if one of community values is contained
contains(community_elm, ...)
# shortcut to contains: community(no_export, 3561:70)
operator()(community_elm, ...)
# order independent equality comparison
operator==(community_list)
rp-attribute: # next hop router in a static route
next-hop
# to set to 7.7.7.7: next-hop = 7.7.7.7;
# to set to router's own address: next-hop = self;
operator=(union ipv4_address, enum[self])
rp-attribute: # cost of a static route
cost
operator=(integer[0, 65535])
protocol: BGP4
# as number of the peer router
MANDATORY asno(as_number)
# enable flap damping
OPTIONAL flap_damp()
OPTIONAL flap_damp(integer[0,65535],
# penalty per flap
integer[0,65535],
# penalty value for supression
integer[0,65535],
# penalty value for reuse
integer[0,65535],
# halflife in secs when up
integer[0,65535],
# halflife in secs when down
integer[0,65535])
# maximum penalty
protocol: OSPF
protocol: RIP
protocol: IGRP
protocol: IS-IS
protocol: STATIC
protocol: RIPng
protocol: DVMRP
protocol: PIM-DM
protocol: PIM-SM
protocol: CBT
protocol: MOSPF
Figure 27: RPSL Dictionary
okay so Figure 27 is the initial RPSL dictionary and it is giving full toolkit π§°β¨ It has seven rp-attributes. pref assigns local preference to the routes accepted πΈ med assigns a value to the MULTI_EXIT_DISCRIMINATOR BGP attribute π¦ dpa assigns a value to the DPA BGP attribute π aspath prepends a value to the AS_PATH BGP attribute π£οΈ community assigns a value to, or checks the value of, the community BGP attribute π next-hop assigns next hop routers to static routes π§ and cost assigns a cost to static routes π°
The dictionary defines two types, community_elm and community_list. A community_elm is either a 4-byte unsigned integer, or one of the keywords internet, no_export or no_advertise (defined in [9]). An integer can be written as two 2-byte integers separated by ":", which lets a provider partition the community number space. The provider can use its AS number as the first two bytes and give the last two bytes whatever meaning it wants π«Ά
The initial dictionary (Figure 27) only defines options for the Border Gateway Protocol: asno and flap_damp. The asno option is mandatory, and it is the AS number of the peer router π₯ The flap_damp option is optional, and it tells the router to damp route flaps [21] when importing routes from the peer router π
flap_damp can be specified with or without parameters. If the parameters are missing, they default to:
flap_damp(1000, 2000, 750, 900, 900, 20000)
Here's the vibe: each route flap adds a penalty of 1000, and the route gets suppressed once the penalty hits 2000 π The penalty is cut in half after 15 minutes (900 seconds) of stability, whether the route is up or down. A suppressed route gets reused once the penalty drops below 750. The maximum penalty a route can collect is 20,000, which means the maximum suppress time after a route becomes stable is about 75 minutes β³ These numbers match the default flap damping parameters in several routers, so they're not random π
Policy Actions and Filters Using RP-Attributes
The syntax for a policy action or filter that uses an rp-attribute x looks like this:
x.method(arguments)
x "op" argument
Here, method is a method, and "op" is an operator method of the rp-attribute x. If you use an operator method inside a composite policy filter, it evaluates before the composite policy filter operators (AND, OR, NOT, and the implicit or operator) π§ β¨
The pref rp-attribute can be assigned a positive integer like so:
pref = 10;
The med rp-attribute is giving two options: a positive integer, or the word "igp_cost" π€
med = 0;
med = igp_cost;
The dpa rp-attribute can be assigned a positive integer too:
dpa = 100;
The BGP community attribute is list-valued. It's a list of 4-byte integers, and each one represents a "community" π Here's how you add communities to this rp-attribute:
community .= { 100 };
community .= { NO_EXPORT };
community .= { 3561:10 };
In that last case, the 4-byte integer gets built with the more significant two bytes equal to 3561 and the less significant two bytes equal to 10. Now, deleting communities from the community rp-attribute looks like this:
community.delete(100, NO_EXPORT, 3561:10);
Filters that use the community rp-attribute can be defined like this:
community.contains(100, NO_EXPORT, 3561:10);
community(100, NO_EXPORT, 3561:10); # shortcut
You can also set the community rp-attribute to a whole list of communities:
community = {100, NO_EXPORT, 3561:10, 200};
community = {};
In the first case, the community rp-attribute holds the communities 100, NO_EXPORT, 3561:10, and 200 π In the second case, the community rp-attribute gets cleared π§Ή And if you want to compare it against a list of communities, you do it like this:
community == {100, NO_EXPORT, 3561:10, 200}; # exact match
To influence route selection, the BGP as_path rp-attribute can be made longer by prepending AS numbers to it π£οΈπ
aspath.prepend(AS1);
aspath.prepend(AS1, AS1, AS1);
β οΈ Heads up bestie: these are INVALID, so don't copy them π
med = -50; # -50 is not in the range
med = igp; # igp is not one of the enum values
med.assign(10); # method assign is not defined
community.append(AS3561:20); # the first argument should be 3561
Figure 28 is a more advanced example using the rp-attribute community π AS3561 bases its route selection preference on the community attribute, and other ASes can indirectly affect how AS3561 selects routes by putting the right communities in their route announcements. It's giving puppet-master energy π
aut-num: AS1
export: to AS2 action community.={3561:90};
to AS3 action community.={3561:80};
announce AS1
as-set: AS3561:AS-PEERS
members: AS2, AS3
aut-num: AS3561
import: from AS3561:AS-PEERS
action pref = 10;
accept community(3561:90)
import: from AS3561:AS-PEERS
action pref = 20;
accept community(3561:80)
import: from AS3561:AS-PEERS
action pref = 20;
accept community(3561:70)
import: from AS3561:AS-PEERS
action pref = 0;
accept ANY
Figure 28: Policy example using the community rp-attribute.
8. Advanced route Class β¨
8.1 Specifying Aggregate Routes π
okay bestie, it's aggregation time π¦ five attributes do the heavy lifting here: aggr-bndry, aggr-mtd, export-comps, inject, and holes [11]. A route object counts as an aggregate route if any of them shows up, except inject, which kinda goes its own way π
. The origin is the AS doing the aggregating, aka the aggregator AS. Quick vocab so nobody gets lost β¨: "aggregate" is the route that gets generated, "component" is a route used to build the aggregate's path attributes, and "more specifics" is any route that's more specific than the aggregate, whether or not it helped build it πΈ
The components attribute decides which component routes form the aggregate. Its syntax goes like this:
components: [ATOMIC] [[<filter>] [protocol <protocol> <filter> ...]]
Here <protocol> is a routing protocol name like BGP4, OSPF or RIP (the valid names live in the dictionary), and <filter> is a policy expression π§ Routes that match one of those filters and were learned from the matching protocol get used to form the aggregate. If you leave out <protocol>, it defaults to any protocol. Every <filter> secretly has an "AND" with the more specifics of the aggregate, so only the component routes get picked. If you use the ATOMIC keyword, the aggregation is done atomically [11]. No <filter>? It defaults to more specifics. And if the components attribute is missing entirely, all more specifics without the ATOMIC keyword get used π
Check out these two route objects:
route: 128.8.0.0/15
origin: AS1
components: <^AS2>
route: 128.8.0.0/15
origin: AS1
components: protocol BGP4 {128.8.0.0/16^+}
protocol OSPF {128.9.0.0/16^+}
Figure 29: Two aggregate route objects.
In the first one, more specifics of 128.8.0.0/15 with AS paths starting with AS2 get aggregated π In the second one, some routes learned from BGP and some learned from OSPF get aggregated together π
The aggr-bndry attribute is an AS expression over AS numbers and sets (see Section 5.6). Its result is the set of ASes that make up the aggregation boundary π If aggr-bndry is missing, the origin AS is the only one in the boundary. Outside the boundary, only the aggregate gets exported and the more specifics get suppressed π Inside the boundary, though, the more specifics still get swapped around.
The aggr-mtd attribute says how the aggregate gets generated. Its syntax:
aggr-mtd: inbound
| outbound [<as-expression>]
Here <as-expression> is an expression over AS numbers and sets (see Section 5.6). If it's missing, it defaults to AS-ANY. With outbound aggregation, the more specifics stay inside the AS, and the aggregate gets formed at every inter-AS boundary with ASes in <as-expression> before it's exported. ASes inside the aggregating boundary are the exception, since aggr-bndry is enforced no matter what <as-expression> says. With inbound aggregation, the aggregate gets formed at all inter-AS boundaries before routes are imported into the aggregator AS. Heads up: <as-expression> can't be used with inbound aggregation π« And if aggr-mtd is missing, it defaults to "outbound AS-ANY" π
Here's an outbound multi-AS example:
route: 128.8.0.0/15 route: 128.8.0.0/15
origin: AS1 origin: AS2
components: {128.8.0.0/15^-} components: {128.8.0.0/15^-}
aggr-bndry: AS1 OR AS2 aggr-bndry: AS1 OR AS2
aggr-mtd: outbound AS-ANY aggr-mtd: outbound AS-ANY
Figure 30: Outbound multi-AS aggregation example.
In this one, AS1 and AS2 team up and only announce the less specific 128.8.0.0/15 to the outside world, while swapping more specifics between themselves π€ This is super useful when some components live in AS1 and others live in AS2 β¨
When routes get aggregated, the goal is to export only the aggregate and suppress the more specifics outside the boundary. Sometimes, though, policy or topology stuff (like a multi-homed component) means some components have to be exported anyway π₯Ί That's what export-comps is for. It's an RPSL filter that matches the more specifics that should go outside the boundary. If the attribute is missing, the more specifics don't get exported outside the boundary. Also, the export-comps filter has an implicit "AND" with the more specifics of the aggregate π
This example shows an outbound aggregation with an export exception:
route: 128.8.0.0/15
origin: AS1
components: {128.8.0.0/15^-}
aggr-mtd: outbound AS-ANY
export-comps: {128.8.8.0/24}
Figure 31: Outbound aggregation with export exception.
Here 128.8.8.0/24 gets exported outside AS1 alongside the aggregate. That's handy when 128.8.8.0/24 is a multi-homed site connecting to AS1 and some other AS π§
The inject attribute says which routers do the aggregation and when. Its syntax:
inject: [at <router-expression>] ...
[action <action>]
[upon <condition>]
Here <action> is an action specification (see Section 6.1.1), <condition> is a boolean expression (more on that below), and <router-expression> is described in Section 5.6 β¨
Every router in <router-expression> and in the aggregator AS does the aggregation. If you don't specify a <router-expression>, all routers inside the aggregator AS do it. The <action> can set path attributes on the aggregate, like giving it a preference π₯
The upon clause is a boolean condition, and the aggregate only gets generated if that condition is true. <condition> uses the logical operators AND and OR (NOT is not allowed π
ββοΈ) over these:
HAVE-COMPONENTS { list of prefixes }
EXCLUDE { list of prefixes }
STATIC
The prefixes in HAVE-COMPONENTS can only be more specifics of the aggregate. It evaluates to true when all the listed prefixes are in the aggregating router's routing table. The list can also use prefix ranges (with the operators ^-, ^+, ^n, and ^n-m). In that case, at least one prefix from each range has to be in the routing table for it to be true π The prefixes in EXCLUDE can be anything. It evaluates to true when none of the listed prefixes are in the routing table. Ranges work here too, and no prefix in the range should be in the routing table. The keyword STATIC always evaluates to true π And if there's no upon clause, the aggregate gets generated if and only if there's a component in the routing table (a more specific that matches the components filter) πΈ
Here are two examples of inject:
route: 128.8.0.0/15
origin: AS1
components: {128.8.0.0/15^-}
aggr-mtd: outbound AS-ANY
inject: at 1.1.1.1 action dpa = 100;
inject: at 1.1.1.2 action dpa = 110;
route: 128.8.0.0/15
origin: AS1
components: {128.8.0.0/15^-}
aggr-mtd: outbound AS-ANY
inject: upon HAVE-COMPONENTS {128.8.0.0/16, 128.9.0.0/16}
holes: 128.8.8.0/24
Figure 32: Examples of inject.
In the first case, the aggregate gets injected at two routers, and each one sets the dpa path attribute to a different value π In the second case, the aggregate only gets generated if both 128.8.0.0/16 and 128.9.0.0/16 are in the routing table. In the first case, just one of them is enough for injection π
The holes attribute lists the component prefixes that aren't reachable through the aggregate (maybe that chunk of address space is unallocated π« ). It's really useful for diagnosis π In Figure 32, the second example has a hole: 128.8.8.0/24. That could happen if a customer switches providers and takes that part of the address space with them π§³
8.1.1 Interaction with policies in aut-num class β¨
An aggregate that gets formed is only announced to other ASes if the AS's export policies allow exporting the aggregate π‘οΈ Once the aggregate exists, the more specifics get suppressed from export, except to the ASes in aggr-bndry and except the components listed in export-comps. For those exceptions to actually happen, the AS's export policies have to explicitly allow them π
If an aggregate doesn't get formed (because of the upon clause), then the more specifics can be exported to other ASes, but only if the AS's export policies allow it π So, before any route (aggregate or more specific) gets exported, it's filtered twice: once based on the route objects, and once based on the AS's export policies. Double check, no cap π«Ά
Here's an interaction example:
route: 128.8.0.0/16
origin: AS1
route: 128.9.0.0/16
origin: AS1
route: 128.8.0.0/15
origin: AS1
aggr-bndry: AS1 or AS2 or AS3
aggr-mtd: outbound AS3 or AS4 or AS5
components: {128.8.0.0/16, 128.9.0.0/16}
inject: upon HAVE-COMPONENTS {128.9.0.0/16, 128.8.0.0/16}
aut-num: AS1
export: to AS2 announce AS1
export: to AS3 announce AS1 and not {128.9.0.0/16}
export: to AS4 announce AS1
export: to AS5 announce AS1
export: to AS6 announce AS1
Figure 33: Interaction with policies in aut-num class.
Looking at the route objects, the more specifics 128.8.0.0/16 and 128.9.0.0/16 should get exchanged between AS1, AS2 and AS3, since that's the aggregation boundary π€ Outbound aggregation goes to AS4 and AS5, but not to AS3, because AS3 is inside the boundary. The aut-num object lets both components go to AS2, but only 128.8.0.0/16 goes to AS3. The aggregate can only form if both components are available π So in this case, only the aggregate gets announced to AS4 and AS5. But if one component is missing, the aggregate won't form, and any available component or more specific gets exported to AS4 and AS5 instead π¦ Whether aggregation happens or not, AS6 only ever gets the more specifics, since it's not listed in aggr-mtd π
When you're doing an inbound aggregation, configuration generators can drop the aggregation statements on routers where the AS's import policy blocks importing any more specifics π§Ή
8.1.2. Ambiguity resolution with overlapping aggregates π§©
okay bestie, what happens when you've got a bunch of aggregate routes and they overlap? π Like, one is less specific than the other. Then they must be evaluated from more specific to less specific, no cap π . When an outbound aggregation is done for a peer, the aggregate and the components listed in that peer's export-comps attribute are available for making the next less specific aggregate. Components that aren't in export-comps are not available, so they're out of the picture π. A route is exportable to an AS if it's the least specific aggregate exportable to that AS, or if it's listed in the export-comps attribute of an exportable route. This is a recursive definition, so it loops back on itself, and that's kind of iconic π.
route: 128.8.0.0/15
origin: AS1
aggr-bndry: AS1 or AS2
aggr-mtd: outbound
inject: upon HAVE-COMPONENTS {128.8.0.0/16, 128.9.0.0/16}
route: 128.10.0.0/15
origin: AS1
aggr-bndry: AS1 or AS3
aggr-mtd: outbound
inject: upon HAVE-COMPONENTS {128.10.0.0/16, 128.11.0.0/16}
export-comps: {128.11.0.0/16}
route: 128.8.0.0/14
origin: AS1
aggr-bndry: AS1 or AS2 or AS3
aggr-mtd: outbound
inject: upon HAVE-COMPONENTS {128.8.0.0/15, 128.10.0.0/15}
export-comps: {128.10.0.0/15}
Figure 34: Overlapping aggregations.
Okay, so in Figure 34 π, AS1 and AS2 team up to aggregate 128.8.0.0/16 and 128.9.0.0/16 into 128.8.0.0/15. AS1 and AS3 do their own thing with 128.10.0.0/16 and 128.11.0.0/16, making 128.10.0.0/15. But all together, they squish those four routes into 128.8.0.0/14 β¨. Assuming all four components are available, a router in AS1 for an outside AS, let's say AS4, will first generate 128.8.0.0/15 and 128.10.0.0/15. That makes 128.8.0.0/15, 128.10.0.0/15, and its exception 128.11.0.0/16 available for generating 128.8.0.0/14. So the router builds 128.8.0.0/14 from those three routes. For AS4, that means 128.8.0.0/14 is exportable, and so are its exception 128.10.0.0/15 and that one's exception 128.11.0.0/16 π¦.
For AS2, a router in AS1 will only generate 128.10.0.0/15. So 128.10.0.0/15 and its exception 128.11.0.0/16 are exportable. Also, 128.8.0.0/16 and 128.9.0.0/16 are still exportable, since they didn't take part in an aggregate that's exportable to AS2 πΈ.
Similarly, for AS3, a router in AS1 will only generate 128.8.0.0/15. In this case, 128.8.0.0/15, 128.10.0.0/16, and 128.11.0.0/16 are exportable π.
8.2. Specifying Static Routes π£οΈ
okay so the inject attribute can be used to specify static routes by using "upon static" as the condition π«Ά:
inject: [at <router-expression>] ...
[action <action>]
upon static
Here's the vibe: the routers in <router-expression> run the <action> and inject the route into the interAS routing system statically π₯. The <action> can set certain route attributes, like a next-hop router or a cost.
In the following example, the router 7.7.7.1 injects the route 128.7.0.0/16 π§. The next-hop routers for this route (there are two of them in this example) are 7.7.7.2 and 7.7.7.3. The route has a cost of 10 over 7.7.7.2 and a cost of 20 over 7.7.7.3 π.
route: 128.7.0.0/16
origin: AS1
inject: at 7.7.7.1 action next-hop = 7.7.7.2; cost = 10; upon static
inject: at 7.7.7.1 action next-hop = 7.7.7.3; cost = 20; upon static
9. inet-rtr Class π₯οΈ
okay so routers get specified using the inet-rtr class π. The attributes of the inet-rtr class are shown in Figure 35. The inet-rtr attribute is a valid DNS name of the router being described. Each alias attribute, if present, is a canonical DNS name for the router. The local-as attribute specifies the AS number of the AS that owns and operates this router π.
Attribute Value Type
inet-rtr <dns-name> mandatory, single-valued, class key
alias <dns-name> optional, multi-valued
local-as <as-number> mandatory, single-valued
ifaddr see description in text mandatory, multi-valued
peer see description in text optional, multi-valued
member-of list of <rtr-set-names> optional, multi-valued
Figure 35: inet-rtr Class Attributes
The value of an ifaddr attribute has this syntax: <ipv4-address> masklen <integer> [action <action>]
The IP address and the mask length are mandatory for each interface π. You can optionally include an action to set other parameters for that interface.
Figure 36 shows an example inet-rtr object π. The name of the router is "amsterdam.ripe.net", and "amsterdam1.ripe.net" is a canonical name for it. The router is connected to 4 networks, and its IP addresses and mask lengths in those networks are listed in the ifaddr attributes.
inet-rtr: Amsterdam.ripe.net
alias: amsterdam1.ripe.net
local-as: AS3333
ifaddr: 192.87.45.190 masklen 24
ifaddr: 192.87.4.28 masklen 24
ifaddr: 193.0.0.222 masklen 27
ifaddr: 193.0.0.158 masklen 27
peer: BGP4 192.87.45.195 asno(AS3334), flap_damp()
Figure 36: inet-rtr Objects
Each peer attribute, if present, specifies a protocol peering with another router. The value of a peer attribute has this syntax:
<protocol> <ipv4-address> <options>
| <protocol> <inet-rtr-name> <options>
| <protocol> <rtr-set-name> <options>
| <protocol> <peering-set-name> <options>
Here, <protocol> is a protocol name, <ipv4-address> is the IP address of the peer router, and <options> is a comma separated list of peering options for <protocol>. Instead of the peer's IP address, you can use its inet-rtr-name π . Possible protocol names and attributes are defined in the dictionary (please see Section 7). In the example above, the router has a BGP peering with the router 192.87.45.195 in AS3334, and it turns flap damping on when importing routes from that router π.
You can also specify a whole group of peers instead of just one, using the <rtr-set-name> and <peering-set-name> forms π. If the <peering-set-name> form is used, only the peerings in the corresponding peering set that are with this router are included. Figure 37 shows an example inet-rtr object with peering groups.
rtr-set: rtrs-ibgp-peers
members: 1.1.1.1, 2.2.2.2, 3.3.3.3
peering-set: prng-ebgp-peers
peering: AS3334 192.87.45.195
peering: AS3335 192.87.45.196
inet-rtr: Amsterdam.ripe.net
alias: amsterdam1.ripe.net
local-as: AS3333
ifaddr: 192.87.45.190 masklen 24
ifaddr: 192.87.4.28 masklen 24
ifaddr: 193.0.0.222 masklen 27
ifaddr: 193.0.0.158 masklen 27
peer: BGP4 rtrs-ibgp-peers asno(AS3333), flap_damp()
peer: BGP4 prng-ebgp-peers asno(PeerAS), flap_damp()
Figure 37: inet-rtr Object with peering groups
10. Extending RPSL π±
okay so our experience with earlier routing policy languages and data formats (PRDB [2], RIPE-81 [8], and RIPE-181 [7]) taught us that RPSL had to be extensible π. That's why extensibility was a primary design goal for RPSL. New routing protocols, or new features for existing routing protocols, can be handled easily using RPSL's dictionary class. New classes, or new attributes for existing classes, can also be added β¨.
This section gives guidelines for extending RPSL. The guidelines are designed with an eye toward keeping backward compatibility with existing tools and databases π«Ά. We next list the available options for extending RPSL, from most preferred to least preferred.
10.1. Extensions by changing the dictionary class π
The dictionary class is the main mechanism provided for extending RPSL. Dictionary objects define routing policy attributes, types, and routing protocols.
We recommend updating the RPSL dictionary to include appropriate rp-attribute and protocol definitions whenever new path attributes or router features are introduced. For example, in an earlier version of the RPSL document, it was only possible to specify that a router performs route flap damping on a peer. It wasn't possible to specify the parameters of route flap damping. Later on, the parameters were added by changing the dictionary π.
When changing the dictionary, full compatibility should be maintained. For example, in our flap damping case, we made the parameter specification optional, in case some ISPs didn't want that level of detail. This also achieved compatibility. Any object registered without the parameters will continue to be valid. Any tool based on RPSL is expected to take a default action on routing policy attributes that it doesn't understand (e.g. issue a warning and otherwise ignore). So old tools that run into a flap damping specification with parameters will ignore the parameters πΈ.
10.2. Extensions by adding new attributes to existing classes π§
New attributes can be added to any class. To keep full compatibility, new attributes should not contradict the semantics of the objects they're attached to. Any tool that uses the IRR should be designed so that it ignores attributes it doesn't understand. Most existing tools already follow this design principle π.
We recommend adding new attributes to existing classes when a new aspect of a class is discovered. For example, the RPSL route class extends its RIPE-181 predecessor by including several new attributes that enable aggregate and static route specification π¦.
10.3. Extensions by adding new classes ποΈ
New classes can be added to RPSL to store new types of policy data. Providing full compatibility is straightforward as long as existing classes are still understood. Since a tool should only query the IRR for the classes it understands, full compatibility shouldn't be a problem in this case π .
Before adding a new class, ask yourself whether the information in the objects of the new class could have belonged better to some other class π€. For example, if the geographic location of a router needs to be stored in the IRR, it might be tempting to add a new class called, say, router-location class. But the information really belongs to the inet-rtr class, perhaps in a new attribute called location π.
10.4. Extensions by changing the syntax of existing RPSL attributes β οΈ
If all of the methods described above fail to provide the desired extension, it may be necessary to change the syntax of RPSL. Any change in RPSL syntax must provide backwards compatibility, and it should only be considered as a last resort, since full compatibility may not be achievable. However, we require that the old syntax still be valid π₯Ή.
11. Security Considerations π
okay bestie, this part is serious, so read it carefully ππ₯
This document describes RPSL, a language for expressing routing policies. The language defines a maintainer (mntner class) object, which is the entity that controls or "maintains" the objects stored in a database expressed by RPSL. Requests from maintainers can be authenticated with various techniques, as defined by the "auth" attribute of the maintainer object π‘οΈ.
The exact protocols that IRR's use to communicate RPSL objects are beyond the scope of this document. However, it's envisioned that several techniques may be used, ranging from interactive query/update protocols to store and forward protocols similar to or based on electronic mail (or even voice telephone calls) π. No matter which protocols are used in a given situation, it's expected that appropriate security techniques, such as IPSEC, TLS, or PGP/MIME, will be utilized ππ.
12. Acknowledgements β¨
okay bestie, big thank-you energy π«Ά the authors want to shoutout these legends for their comments and suggestions: Jessica Yu, Randy Bush, Alan Barrett, Bill Manning, Sue Hares, Ramesh Govindan, Kannan Varadhan, Satish Kumar, Craig Labovitz, Rusty Eddy, David J. LeRoy, David Whipple, Jon Postel, Deborah Estrin, Elliot Schwartz, Joachim Schmitz, Mark Prior, Tony Przygienda, David Woodgate, Rob Coltun, Sanjay Wadhwa, Ardas Cilingiroglu, and the participants of the IETF RPS Working Group π iconic group, no notes.
References
- [1] Internet routing registry. procedures.
http://www.ra.net/RADB.tools.docs/,http://www.ripe.net/db/doc.html. - [2] Nsfnet policy routing database (prdb). Maintained by MERIT Network Inc., Ann Arbor, Michigan. Contents available from nic.merit.edu.:/nsfnet/announced.networks/nets.tag.now by anonymous ftp.
- [3] Alaettinouglu, C., Bates, T., Gerich, E., Karrenberg, D., Meyer, D., Terpstra, M. and C. Villamizer, "Routing Policy Specification Language (RPSL)", RFC 2280, January 1998.
- [4] C. Alaettinouglu, D. Meyer, and J. Schmitz. Application of routing policy specification language (rpsl) on the internet. Work in Progress.
- [5] T. Bates. Specifying an `internet router' in the routing registry. Technical Report RIPE-122, RIPE, RIPE NCC, Amsterdam, Netherlands, October 1994.
- [6] T. Bates, E. Gerich, L. Joncheray, J-M. Jouanigot, D. Karrenberg, M. Terpstra, and J. Yu. Representation of ip routing policies in a routing registry. Technical Report ripe-181, RIPE, RIPE NCC, Amsterdam, Netherlands, October 1994.
- [7] Bates, T., Gerich, E., Joncheray, L., Jouanigot, J-M., Karrenberg, D., Terpstra, M. and J. Yu, " Representation of IP Routing Policies in a Routing Registry", RFC 1786, March 1995.
- [8] T. Bates, J-M. Jouanigot, D. Karrenberg, P. Lothberg, and M. Terpstra. Representation of ip routing policies in the ripe database. Technical Report ripe-81, RIPE, RIPE NCC, Amsterdam, Netherlands, February 1993.
- [9] Chandra, R., Traina, P. and T. Li, "BGP Communities Attribute", RFC 1997, August 1996.
- [10] Crocker, D., "Standard for ARPA Internet Text Messages", STD 11, RFC 822, August 1982.
- [11] Fuller, V., Li, T., Yu, J. and K. Varadhan, "Classless Inter-Domain Routing (CIDR): an Address Assignment and Aggregation Strategy", RFC 1519, September 1993.
- [12] D. Karrenberg and T. Bates. Description of inter-as networks in the ripe routing registry. Technical Report RIPE-104, RIPE, RIPE NCC, Amsterdam, Netherlands, December 1993.
- [13] D. Karrenberg and M. Terpstra. Authorisation and notification of changes in the ripe database. Technical Report ripe-120, RIPE, RIPE NCC, Amsterdam, Netherlands, October 1994.
- [14] B. W. Kernighan and D. M. Ritchie. The C Programming Language. Prentice-Hall, 1978.
- [15] A. Lord and M. Terpstra. Ripe database template for networks and persons. Technical Report ripe-119, RIPE, RIPE NCC, Amsterdam, Netherlands, October 1994.
- [16] A. M. R. Magee. Ripe ncc database documentation. Technical Report RIPE-157, RIPE, RIPE NCC, Amsterdam, Netherlands, May 1997.
- [17] Mockapetris, P., "Domain names - concepts and facilities", STD 13, RFC 1034, November 1987.
- [18] Y. Rekhter. Inter-domain routing protocol (idrp). Journal of Internetworking Research and Experience, 4:61--80, 1993.
- [19] Rekhter Y. and T. Li, "A Border Gateway Protocol 4 (BGP-4)", RFC 1771, March 1995.
- [20] C. Villamizar, C. Alaettinouglu, D. Meyer, S. Murphy, and C. Orange. Routing policy system security", Work in Progress.
- [21] Villamizar, C., Chandra, R. and R. Govindan, "BGP Route Flap Damping", RFC 2439, November 1998.
- [22] J. Zsako, "PGP authentication for ripe database updates", Work in Progress.
A. Routing Registry Sites πΈ
the routing registries as of November 1996 were RIPE, RADB, CANet, MCI and ANS. if you want the current list, you can contact one of these registries and ask them directly π
B. Grammar Rules π¦
okay so this section is the formal grammar for RPSL π the basic data types are defined in Section 2, and we don't write formal grammar rules for attributes whose values are basic types or lists of basic types. the rules are written in the input language of the GNU Bison parser, which means you can literally cut and paste them into that program π slay.
//**** Generic Attributes **********************************************
changed_attribute: ATTR_CHANGED TKN_EMAIL TKN_INT
//**** aut-num class ***************************************************
//// as_expression /////////////////////////////////////////////////////
opt_as_expression:
| as_expression
as_expression: as_expression OP_OR as_expression_term
| as_expression_term
as_expression_term: as_expression_term OP_AND as_expression_factor
| as_expression_term KEYW_EXCEPT as_expression_factor
| as_expression_factor
as_expression_factor: '(' as_expression ')'
| as_expression_operand
as_expression_operand: TKN_ASNO
| TKN_ASNAME
//// router_expression /////////////////////////////////////////////////
opt_router_expression:
| router_expression
opt_router_expression_with_at:
| KEYW_AT router_expression
router_expression: router_expression OP_OR router_expression_term
| router_expression_term
router_expression_term: router_expression_term OP_AND
router_expression_factor
| router_expression_term KEYW_EXCEPT router_expression_factor
| router_expression_factor
router_expression_factor: '(' router_expression ')'
| router_expression_operand
router_expression_operand: TKN_IPV4
| TKN_DNS
| TKN_RTRSNAME
//// peering ///////////////////////////////////////////////////////////
peering: as_expression opt_router_expression opt_router_expression_with_at
| TKN_PRNGNAME
//// action ////////////////////////////////////////////////////////////
opt_action:
| KEYW_ACTION action
action: single_action
| action single_action
single_action: TKN_RP_ATTR '.' TKN_WORD '(' generic_list ')' ';'
| TKN_RP_ATTR TKN_OPERATOR list_item ';'
| TKN_RP_ATTR '(' generic_list ')' ';'
| TKN_RP_ATTR '[' generic_list ']' ';'
| ';'
//// filter ////////////////////////////////////////////////////////////
filter: filter OP_OR filter_term
| filter filter_term %prec OP_OR
| filter_term
filter_term : filter_term OP_AND filter_factor
| filter_factor
filter_factor : OP_NOT filter_factor
| '(' filter ')'
| filter_operand
filter_operand: KEYW_ANY
| '<' filter_aspath '>'
| filter_rp_attribute
| TKN_FLTRNAME
| filter_prefix
filter_prefix: filter_prefix_operand OP_MS
| filter_prefix_operand
filter_prefix_operand: TKN_ASNO
| KEYW_PEERAS
| TKN_ASNAME
| TKN_RSNAME
| '{' opt_filter_prefix_list '}'
opt_filter_prefix_list:
| filter_prefix_list
filter_prefix_list: filter_prefix_list_prefix
| filter_prefix_list ',' filter_prefix_list_prefix
filter_prefix_list_prefix: TKN_PRFXV4
| TKN_PRFXV4RNG
filter_aspath: filter_aspath '|' filter_aspath_term
| filter_aspath_term
filter_aspath_term: filter_aspath_term filter_aspath_closure
| filter_aspath_closure
filter_aspath_closure: filter_aspath_closure '*'
| filter_aspath_closure '?'
| filter_aspath_closure '+'
| filter_aspath_factor
filter_aspath_factor: '^'
| '$'
| '(' filter_aspath ')'
| filter_aspath_no
filter_aspath_no: TKN_ASNO
| KEYW_PEERAS
| TKN_ASNAME
| '.'
| '[' filter_aspath_range ']'
| '[' '^' filter_aspath_range ']'
filter_aspath_range:
| filter_aspath_range TKN_ASNO
| filter_aspath_range KEYW_PEERAS
| filter_aspath_range '.'
| filter_aspath_range TKN_ASNO '-' TKN_ASNO
| filter_aspath_range TKN_ASNAME
filter_rp_attribute: TKN_RP_ATTR '.' TKN_WORD '(' generic_list ')'
| TKN_RP_ATTR TKN_OPERATOR list_item
| TKN_RP_ATTR '(' generic_list ')'
| TKN_RP_ATTR '[' generic_list ']'
//// peering action pair ///////////////////////////////////////////////
import_peering_action_list: KEYW_FROM peering opt_action
| import_peering_action_list KEYW_FROM peering opt_action
export_peering_action_list: KEYW_TO peering opt_action
| export_peering_action_list KEYW_TO peering opt_action
//// import/export factor //////////////////////////////////////////////
import_factor: import_peering_action_list KEYW_ACCEPT filter
import_factor_list: import_factor ';'
| import_factor_list import_factor ';'
export_factor: export_peering_action_list KEYW_ANNOUNCE filter
export_factor_list: export_factor ';'
| export_factor_list export_factor ';'
//// import/export term ////////////////////////////////////////////////
import_term: import_factor ';'
| '{' import_factor_list '}'
export_term: export_factor ';'
| '{' export_factor_list '}'
//// import/export expression //////////////////////////////////////////
import_expression: import_term
| import_term KEYW_REFINE import_expression
| import_term KEYW_EXCEPT import_expression
export_expression: export_term
| export_term KEYW_REFINE export_expression
| export_term KEYW_EXCEPT export_expression
//// protocol ///////////////////////////////////////////////////////////
opt_protocol_from:
| KEYW_PROTOCOL tkn_word
opt_protocol_into:
| KEYW_INTO tkn_word
//**** import/export attributes ****************************************
import_attribute: ATTR_IMPORT
| ATTR_IMPORT opt_protocol_from opt_protocol_into import_factor
export_attribute: ATTR_EXPORT
| ATTR_EXPORT opt_protocol_from opt_protocol_into export_factor
opt_default_filter:
| KEYW_NETWORKS filter
default_attribute: ATTR_DEFAULT KEYW_TO peering
filter_attribute: ATTR_FILTER filter
peering_attribute: ATTR_PEERING peering
//**** inet-rtr class **************************************************
ifaddr_attribute: ATTR_IFADDR TKN_IPV4 KEYW_MASKLEN TKN_INT opt_action
//// peer attribute ////////////////////////////////////////////////////
opt_peer_options:
| peer_options
peer_options: peer_option
| peer_options ',' peer_option
peer_option: tkn_word '(' generic_list ')'
peer_id: TKN_IPV4
| TKN_DNS
| TKN_RTRSNAME
| TKN_PRNGNAME
peer_attribute: ATTR_PEER tkn_word peer_id opt_peer_options
//**** route class *****************************************************
aggr_bndry_attribute: ATTR_AGGR_BNDRY as_expression
aggr_mtd_attribute: ATTR_AGGR_MTD KEYW_INBOUND
| ATTR_AGGR_MTD KEYW_OUTBOUND opt_as_expression
//// inject attribute //////////////////////////////////////////////////
opt_inject_expression:
| KEYW_UPON inject_expression
inject_expression: inject_expression OP_OR inject_expression_term
| inject_expression_term
inject_expression_term: inject_expression_term OP_AND
inject_expression_factor
| inject_expression_factor
inject_expression_factor: '(' inject_expression ')'
| inject_expression_operand
inject_expression_operand: KEYW_STATIC
| KEYW_HAVE_COMPONENTS '{' opt_filter_prefix_list '}'
| KEYW_EXCLUDE '{' opt_filter_prefix_list '}'
inject_attribute: ATTR_INJECT opt_router_expression_with_at opt_action
opt_inject_expression
//// components attribute //////////////////////////////////////////////
opt_atomic:
| KEYW_ATOMIC
components_list:
| filter
| components_list KEYW_PROTOCOL tkn_word filter
components_attribute: ATTR_COMPONENTS opt_atomic components_list
//**** route-set *******************************************************
opt_rs_members_list: /* empty list */
| rs_members_list
rs_members_list: rs_member
| rs_members_list ',' rs_member
rs_member: TKN_ASNO
| TKN_ASNO OP_MS
| TKN_ASNAME
| TKN_ASNAME OP_MS
| TKN_RSNAME
| TKN_RSNAME OP_MS
| TKN_PRFXV4
| TKN_PRFXV4RNG
rs_members_attribute: ATTR_RS_MEMBERS opt_rs_members_list
//**** dictionary ******************************************************
rpattr_attribute: ATTR_RP_ATTR TKN_WORD methods
| ATTR_RP_ATTR TKN_RP_ATTR methods
methods: method
| methods method
method: TKN_WORD '(' ')'
| TKN_WORD '(' typedef_type_list ')'
| TKN_WORD '(' typedef_type_list ',' TKN_3DOTS ')'
| KEYW_OPERATOR TKN_OPERATOR '(' typedef_type_list ')'
| KEYW_OPERATOR TKN_OPERATOR '(' typedef_type_list ',' TKN_3DOTS ')'
//// typedef attribute ////////////////////////////////////////////////
typedef_attribute: ATTR_TYPEDEF TKN_WORD typedef_type
typedef_type_list: typedef_type
| typedef_type_list ',' typedef_type
typedef_type: KEYW_UNION typedef_type_list
| KEYW_RANGE KEYW_OF typedef_type
| TKN_WORD
| TKN_WORD '[' TKN_INT ',' TKN_INT ']'
| TKN_WORD '[' TKN_REAL ',' TKN_REAL ']'
| TKN_WORD '[' enum_list ']'
| KEYW_LIST '[' TKN_INT ':' TKN_INT ']' KEYW_OF typedef_type
| KEYW_LIST KEYW_OF typedef_type
enum_list: tkn_word
| enum_list ',' tkn_word
//// protocol attribute ////////////////////////////////////////////////
protocol_attribute: ATTR_PROTOCOL tkn_word protocol_options
protocol_options:
| protocol_options protocol_option
protocol_option: KEYW_MANDATORY method
| KEYW_OPTIONAL method
//**** Token Definitions ***********************************************
//// flex macros used in token definitions /////////////////////////////
INT [[:digit:]]+
SINT [+-]?{INT}
REAL [+-]?{INT}?\.{INT}({WS}*E{WS}*[+-]?{INT})?
NAME [[:alpha:]]([[:alnum:]_-]*[[:alnum:]])?
ASNO AS{INT}
ASNAME AS-[[:alnum:]_-]*[[:alnum:]]
RSNAME RS-[[:alnum:]_-]*[[:alnum:]]
RTRSNAME RTRS-[[:alnum:]_-]*[[:alnum:]]
PRNGNAME PRNG-[[:alnum:]_-]*[[:alnum:]]
FLTRNAME FLTR-[[:alnum:]_-]*[[:alnum:]]
IPV4 [0-9]+(\.[0-9]+){3,3}
PRFXV4 {IPV4}\/[0-9]+
PRFXV4RNG {PRFXV4}("^+"|"^-"|"^"{INT}|"^"{INT}-{INT})
ENAMECHAR [^()<>,;:\\\"\.[\] \t\r]
ENAME ({ENAMECHAR}+(\.{ENAMECHAR}+)*\.?)|(\"[^\"@\\\r\n]+\")
DNAME [[:alnum:]_-]+
//// Token Definitions ////////////////////////////////////////////////
TKN_INT {SINT}
TKN_INT {INT}:{INT} if each {INT} is two octets
TKN_INT {INT}.{INT}.{INT}.{INT} if each {INT} is one octet
TKN_REAL {REAL}
TKN_STRING Same as in programming language C
TKN_IPV4 {IPV4}
TKN_PRFXV4 {PRFXV4}
TKN_PRFXV4RNG {PRFXV4RNG}
TKN_ASNO {ASNO}
TKN_ASNAME (({ASNO}|peeras|{ASNAME}):)*{ASNAME}\
(:({ASNO}|peeras|{ASNAME}))*
TKN_RSNAME (({ASNO}|peeras|{RSNAME}):)*{RSNAME}\
(:({ASNO}|peeras|{RSNAME}))*
TKN_RTRSNAME (({ASNO}|peeras|{RTRSNAME}):)*{RTRSNAME}\
(:({ASNO}|peeras|{RTRSNAME}))*
TKN_PRNGNAME (({ASNO}|peeras|{PRNGNAME}):)*{PRNGNAME}\
(:({ASNO}|peeras|{PRNGNAME}))*
TKN_FLTRNAME (({ASNO}|peeras|{FLTRNAME}):)*{FLTRNAME}\
(:({ASNO}|peeras|{FLTRNAME}))*
TKN_BOOLEAN true|false
TKN_RP_ATTR {NAME} if defined in dictionary
TKN_WORD {NAME}
TKN_DNS {DNAME}("."{DNAME})+
TKN_EMAIL {ENAME}@({DNAME}("."{DNAME})+|{IPV4})
C. Changes from RFC 2280 β¨
Okay bestie, so RFC 2280 [3] is the earlier version of RPSL πΈ This section is the recap of everything that's changed since then, and honestly there's a lot of glow-up here π
- It's now possible to write integers as a sequence of four 1-octet integers (e.g.
1.1.1.1) or as a sequence of two 2-octet integers (e.g.3561:70). Check out Section 2 for the deets π¦ - The address prefix range definition got extended, so an address prefix is also an address prefix range now. See Section 2 π
- The semantics for a range operator applied to a set containing address prefix ranges are now defined (e.g.
{30.0.0.0/8^24-28}^27-30). Go look at Section 2 π₯ - All dates are in UTC now π°οΈ See Section 2.
- The plus (
+) character is added to space and tab characters for splitting an attribute's value across multiple lines. So you can start the following lines with a space, a tab, or a plus (+) character β¨ See Section 2. - The withdrawn attribute of the route class is removed from the language π bye bye.
- The filter-set class is introduced π§ See Section 5.4.
- The rtr-set class is introduced π See Section 5.5.
- The peering-set class is introduced π See Section 5.6.
- Filters can now refer to filter-set names. See Section 5.4 π
- Peerings can now refer to peering-set and rtr-set names. Both local and peer routers can be specified using router expressions. See Section 5.6 π
- The peer attribute of the inet-rtr class can now refer to peering-set and rtr-set names. See Section 9 π«Ά
- The syntax and semantics of union and list types and the typedef attribute have changed. See Section 7 π
- In the initial dictionary, the typedef attribute defining the community_elm, and the rp-attribute defining the community attribute, have changed. See Section 7 π
- Guidelines for extending RPSL are added. See Section 10 πΈ
- Formal grammar rules are added. See Appendix B π¦
D. Authors' Addresses π
Cengiz Alaettinoglu
USC/Information Sciences Institute
EMail: cengiz@isi.edu
Curtis Villamizar
Avici Systems
EMail: curtis@avici.com
Elise Gerich
At Home Network
EMail: epg@home.net
David Kessens
Qwest Communications
EMail: David.Kessens@qwest.net
David Meyer
University of Oregon
EMail: meyer@antc.uoregon.edu
Tony Bates
Cisco Systems, Inc.
EMail: tbates@cisco.com
Daniel Karrenberg
RIPE NCC
EMail: dfk@ripe.net
Marten Terpstra
c/o Bay Networks, Inc.
EMail: marten@BayNetworks.com
Full Copyright Statement π
Copyright (C) The Internet Society (1999). All Rights Reserved.
Okay, so the legal bit, but make it cute π You're totally allowed to copy and share this document, and to make derivative works that comment on it, explain it, or help with its implementation. You can prepare, copy, publish, and distribute them, in whole or in part, with no restrictions of any kind, as long as the copyright notice and this paragraph are included on every copy and derivative work.
BUT the document itself can't be modified in any way. That includes removing the copyright notice or the references to the Internet Society or other Internet organizations. The exceptions are: using it to develop Internet standards, in which case the copyright procedures in the Internet Standards process must be followed, or translating it into languages other than English.
The permissions above are perpetual, and the Internet Society and its successors or assigns won't revoke them π«Ά
This document and the information in it are provided on an "AS IS" basis, and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED. That includes, but isn't limited to, any warranty that using the information here won't infringe any rights, and any implied warranties of merchantability or fitness for a particular purpose π
Acknowledgement π«Ά
Funding for the RFC Editor function is currently provided by the Internet Society β¨
π¦ where this page comes from
- ietf: rfc2622 1999-06
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms