RFC 2280
Routing Policy Specification Language (RPSL)
RFC 2280: Routing Policy Specification Language (RPSL) π
okay bestie, this is RFC 2280, and it's a Standards Track doc, so it's a real spec people are supposed to build against, no cap π It's dated January 1998. There are seven authors: C. Alaettinoglu (USC/Information Sciences Institute), T. Bates (Cisco Systems), E. Gerich (At Home Network), D. Karrenberg (RIPE), D. Meyer (University of Oregon), M. Terpstra (Bay Networks), and C. Villamizar (ANS). The header doesn't say it obsoletes or updates any other RFC π«Ά
Status of this Memo β¨
this doc is an Internet standards track protocol for the Internet community, and it's asking for discussion and suggestions for improvements π¦ for where this protocol stands in standardization, check the current edition of "Internet Official Protocol Standards" (STD 1). Distribution of this memo is unlimited π
Copyright Notice π
Copyright (C) The Internet Society (1998). All Rights Reserved. π
Table of Contents π
1 Introduction 2
2 RPSL Names, Reserved Words, and Representation 3
3 Contact Information 6
3.1 mntner Class . . . . . . . . . . . . . . . . . . . . . . . 6
3.2 person Class . . . . . . . . . . . . . . . . . . . . . . . 8
3.3 role Class . . . . . . . . . . . . . . . . . . . . . . . . 9
4 route Class 10
5 Set Classes 12
5.1 route-set Class . . . . . . . . . . . . . . . . . . . . . . 12
5.2 as-set Class . . . . . . . . . . . . . . . . . . . . . . . 14
5.3 Predefined Set Objects . . . . . . . . . . . . . . . . . . 15
5.4 Hierarchical Set Names . . . . . . . . . . . . . . . . . . 15
6 aut-num Class 16
6.1 import Attribute: Import Policy Specification . . . . . . 16
6.1.1 Peering Specification . . . . . . . . . . . . . . . . . 17
6.1.2 Action Specification . . . . . . . . . . . . . . . . . 19
6.1.3 Filter Specification . . . . . . . . . . . . . . . . . 20
6.1.4 Example Policy Expressions . . . . . . . . . . . . . . 24
6.2 export Attribute: Export Policy Specification . . . . . . 24
6.3 Other Routing Protocols, Multi-Protocol Routing
Protocols, and Injecting Routes Between Protocols . . . . . 25
6.4 Ambiguity Resolution . . . . . . . . . . . . . . . . . . . 26
6.5 default Attribute: Default Policy Specification . . . . . 28
6.6 Structured Policy Specification . . . . . . . . . . . . . . 29
7 dictionary Class 33
7.1 Initial RPSL Dictionary and Example Policy Actions
and Filters . . . . . . . . . . . . . . . . . . . . . . . . . 36
8 Advanced route Class 41
8.1 Specifying Aggregate Routes . . . . . . . . . . . . . . . . 41
8.1.1 Interaction with policies in aut-num class . . . . . . 45
8.1.2 Ambiguity resolution with overlapping aggregates . . . 46
8.2 Specifying Static Routes . . . . . . . . . . . . . . . . . 47
9 inet-rtr Class 48
10 Security Considerations 49
11 Acknowledgements 50
A Routing Registry Sites 51
B Authors' Addresses 52
C Full Copyright Statement 53
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 different levels of the Internet hierarchy, like the Autonomous System (AS) level. And it's SO good because policies can be described in enough detail that low level router configurations can be generated straight from them π€― RPSL is also extensible, so new routing protocols and new protocol features can show up at any time β¨
RPSL is a replacement for the current Internet policy specification language known as RIPE-181 [4] or RFC-1786 [5]. RIPE-81 [6] was the first language deployed in the Internet for specifying routing policies. It was later replaced by RIPE-181 [4]. Through operational use of RIPE-181 it became clear that certain policies cannot be specified, so a more enhanced and more generalized language was needed. RPSL addresses 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 Internet's routing π«Ά RPSL is not designed to be a router configuration language, though π It's designed so that router configurations can be generated from the description of one autonomous system's policy (aut-num class) combined with the description of a router (inet-rtr class). The inet-rtr class mainly gives you the router ID, the autonomous system number of the router, its interfaces, and its peers. That's combined 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 can help with goals like router configurations that protect against accidental (or malicious) distribution of inaccurate routing information, verification of 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 get registered in the Internet Routing Registry (IRR) by the authorized organizations. The registration process is beyond the scope of this document, so if you want more on the IRR, check out [1, 15, 2] π
Here's the class lineup. The "mntner" class defines the 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 with the "aut-num" class, and routes with the "route" class π¦ Sets of ASes and routes can be defined using the "as-set" and "route-set" classes π The "dictionary" class gives the language its extensibility β¨ And the "inet-rtr" class is used to specify routers π§ Plenty of these classes were originally defined in earlier documents [4, 11, 14, 10, 3] and have all been enhanced since π
This document is self-contained, but the reader is encouraged to read RIPE-181 [5] and the associated documents [11, 14, 10, 3] too, since they give a lot of background on the motivation and underlying principles behind RIPE-181 and, as a result, RPSL π And if you want an RPSL tutorial, read the RPSL applications document [2] π
2. RPSL Names, Reserved Words, and Representation β¨
okay so every class has a bunch of attributes, and each attribute stores one piece of info about the objects in that class π some attributes are mandatory (every object of that class has to have them) and some are optional (you can skip them π«Ά). attributes can also be single valued or multiple valued. the class "key" is the set of attributes that uniquely identifies each object, so it's basically the object's ID card πͺͺ
every attribute value has a type. these are the big ones you'll see most. heads up: RPSL is case insensitive π and only ASCII characters are allowed, so no fancy unicode, bestie.
<object-name>
lots of RPSL objects have a name π an <object-name> is made of letters, digits, underscores _, and hyphens -. the first character has to be a letter, and the last one has to be a letter or a digit. these words are reserved by RPSL, so they can't be used as names:
any as-any rs-any peeras
and or not
atomic from to at action accept announce except refine
networks into inbound outbound
names starting with certain prefixes are reserved for certain object types too π§ names starting with as- are reserved for as set names, and names starting with rs- are reserved for route set names.
<as-number>
an AS number x is written as the string ASx πΈ so AS 226 becomes AS226. simple and iconic.
<ipv4-address>
an IPv4 address is four integers from 0 to 255, separated by dots . π for example, 128.9.128.5 is a valid one. in the rest of this document, we may refer to IPv4 addresses as IP addresses, so if you see "IP address" just know it means the same thing β¨
<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, because 0 and 128.9 aren't strings with four integers π
0/0
128.9/16
<address-prefix-range>
an address prefix range is an address prefix followed by one of these range operators π
^-is the exclusive more specifics operator. it means all the more specifics of the prefix, but NOT the prefix itself π ββοΈ for example,128.9.0.0/16^-contains all the more specifics of128.9.0.0/16except128.9.0.0/16itself.^+is the inclusive more specifics operator. it means all the more specifics of the prefix, including the prefix itself π for example,5.0.0.0/8^+contains all the more specifics of5.0.0.0/8, including5.0.0.0/8itself.^n, wherenis an integer, means all the lengthnspecifics of the prefix π for example,30.0.0.0/8^16contains all the more specifics of30.0.0.0/8that are length 16, like30.9.0.0/16.^n-m, wherenandmare integers, means all the lengthnto lengthmspecifics of the prefix π for example,30.0.0.0/8^24-32contains all the more specifics of30.0.0.0/8that are length 24 to 32, like30.9.9.96/28.
range operators also work on address prefix sets β¨ in that case they distribute over every member of the set. so for a route-set (we'll get to those later) called rs-foo, rs-foo^+ contains all the inclusive more specifics of every prefix in rs-foo. iconic behaviour, honestly π
<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). so June 24, 1996 is written as 19960624.
<email-address>
the email address format is as described in RFC-822[8] π
<dns-name>
the DNS name format is as described in RFC-1034[16] π
<nic-handle>
a NIC handle is a uniquely assigned identifier[13] used by routing, address allocation, and other registries to refer to contact information without any ambiguity π«§ the person and role classes are what map NIC handles to actual people's names and contact info.
<free-form>
a free-form value is just a sequence of ASCII characters π¨ anything goes (within ASCII, bestie).
<X-name>
an <X-name> is the name of an object of type X. so <mntner-name> is the name of a mntner object π§Έ
<registry-name>
a registry name is the name of an IRR registry ποΈ the routing registries are listed in Appendix A.
an attribute value can also be a list of any 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.
here's the tea π΅: being list valued and being multiple valued are totally different things, so don't mix them up! 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 hold a list value π
an RPSL object is written out as a list of attribute-value pairs π each pair goes on its own line. the attribute name starts at column 0, then a colon :, then the value. the object ends when a blank line shows up π an attribute's value can be split across several lines if you start the continuation lines with a whitespace character (a space " " or a tab) πͺ and the order of the attribute-value pairs matters, so keep them in order, babe β
an object's description can include comments π¬ a comment can go anywhere in the object's definition. it starts at the first # on a line and runs until the end of that line. whitespace is totally fine to use if it makes things easier to read πΈ
3. Contact Information
the mntner, person and role classes, plus the admin-c, tech-c, mnt-by, changed and source attributes, are all about contact information π«Ά the mntner class also decides which entities can create, delete and update other objects π these classes don't specify routing policies, and each registry might have its own extra or different requirements for them. we're showing the common denominator here, for completeness, which is the RIPE database implementation[15] π for the latest specs, check with your routing registry, since they're the source of truth β¨
3.1. mntner Class
the mntner class defines the entities that can create, delete and update RPSL objects π a provider, before he/she can create RPSL objects, first has to create a mntner object π the attributes of the mntner class are shown in Figure 1, and the mntner class was first described in [11] π¦
the mntner attribute is mandatory, and it's the class key attribute ποΈ its value is an RPSL name. the auth attribute specifies the scheme that will be used to identify and authenticate update requests from this maintainer π its syntax looks like this:
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> mandatory, 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 is the table above, so you can see every attribute at a glance π
here's how auth is written π
auth: <scheme-id> <auth-info>
E.g.
auth: NONE
auth: CRYPT-PW dhjsdfhruewf
auth: MAIL-FROM .*@ripe\.net
the scheme IDs that are currently defined are NONE, MAIL-FROM, PGP and CRYPT-PW β¨ the <auth-info> is extra info that 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 it's a PGP public key ποΈ if you specify multiple auth attributes, an update request that satisfies any one of them is authenticated as coming from the maintainer π«Ά
the upd-to attribute is an email address π§ if someone makes an unauthorized update attempt on an object maintained by this maintainer, an email message gets sent to that address π¨ the mnt-nfy attribute is also an email address, and a notification message gets forwarded there 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, meaning the person to reach out to for technical problems like misconfigurations π οΈ 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 that gets notifications about changes to this object π¬ the mnt-by attribute is a list of mntner object names, and whether a change to this object is authorized depends on any of the referenced maintainer objects π the changed attribute records who last changed this object and when, with this syntax:
changed: <email-address> <YYYYMMDD>
E.g.
changed: johndoe@terabit-labs.nn 19900401
the <email-address> identifies the person who made the last change πββοΈ <YYYYMMDD> is the date of that change π
and the source attribute says which registry the object is registered in ποΈ
Figure 2 shows an example mntner object π¦ in this example, UNIX crypt format password authentication is used π§
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 every RPSL class π their syntax, semantics, and whether they're mandatory, optional, multi-valued, or single-valued are the same across all RPSL classes π
so we won't go over them again in the other sections, bestie π«Ά
3.2. person Class π§
okay so the person class is basically the "who is this human" object π«Ά it doesn't describe routing policy at all, but we still gotta talk about it briefly because SO many policy objects point at person objects. it's been around since [14], so it's not new drama.
the attributes are in Figure 3. the person attribute is the full name of the person. phone and fax-no have their own syntax thing going on, which is in the text right under the table π
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: +<country-code> <city> <subscriber> [ext. <extension>]
E.g.:
phone: +31 20 12334676
phone: +44 123 987654 ext. 4711
Figure 4 shows an example person object, and it's giving real-life vibes πΈ
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 the person object's cousin, except instead of a human being it describes a role that one or more humans perform π§ββοΈ think help desks, network monitoring centers, system administrators, etc. the role object is honestly so smart because the person doing the job can change, but the role itself just... stays. main character energy for job titles π
the attributes of the role class are in Figure 5. the nic-hdl attributes of the person and role classes share the same name space, so they're literally in the same pool. The
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
ok the vibe check: the NIC handle of a role object cannot be used in an admin-c field π
ββοΈ and the trouble attribute of a role object may contain extra contact info to use when a problem shows up in any object that references this role object. Figure 6 shows an example role object π
role: RIPE NCC Operations
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 π¦
okay this is where it gets spicy π₯ each interAS route (also called an interdomain route) that an AS originates gets its own route object. the attributes are 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 puts the route into the interAS routing system. the route and origin pair together is the class key, so that's how you tell them apart π
Attribute Value Type
route <address-prefix> mandatory, single-valued,
class key
origin <as-number> mandatory, single-valued,
class key
withdrawn <date> optional, single-valued
member-of list of <route-set-names> optional, single-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, single-valued
Figure 7: route Class Attributes
Figure 8 shows four route objects. we're leaving out contact attributes such as admin-c, tech-c for brevity π notice that the last two route objects have the same address prefix, 128.8.0.0/16. but they're still totally different route objects because different ASes originate them, so their keys are different. two objects with the same prefix, no drama, just different origins π
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
withdrawn: 19960624
Figure 8: Route Objects
the withdrawn attribute, if it's there, means the originator AS no longer originates that address prefix on the Internet π its value is a date, which is the date it got withdrawn. in Figure 8, the last route object was withdrawn (aka AS2 stopped originating it) on June 24, 1996. rip ποΈ
5. Set Classes π§
when you're writing policies, it's super useful to define sets of objects π for that, we define two classes: route-set and as-set. these classes define a named set. the members can be listed explicitly in the set object's definition, or implicitly by route and aut-num objects referring to the set names, or both at once. iykyk π«Ά
5.1. route-set Class π
the attributes of the route-set class are in Figure 9. the route-set attribute defines the name of the set, and it's an RPSL name that starts with "rs-". the members attribute lists the members of the set. it's a list of address prefixes or other route-set names. also, the route-set class is a set of route prefixes, not a set of RPSL route objects, so don't mix those up π
Attribute Value Type
route-set <object-name> mandatory, single-valued,
class key
members list of <address-prefixes> or optional, single-valued
<route-set-names>
mbrs-by-ref list of <mntner-names> optional, single-valued
Figure 9: route-set Class Attributes
Figure 10 has some example route-set objects. the set rs-foo contains two address prefixes, namely 128.9.0.0/16 and 128.9.0.0/16 (yes, that's what it says π). the set rs-bar contains the members of rs-foo plus the address prefix 128.7.0.0/16. and rs-empty contains no members at all, which is very on-brand for it π
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
route-set: rs-empty
Figure 10: route-set Objects
an address prefix or a route-set name in a members attribute can optionally be followed by a range operator β¨ for example, the following set
route-set: rs-bar
members: 5.0.0.0/8^+, 30.0.0.0/8^24-32, rs-foo^+
contains all the more specifics of 5.0.0.0/8, including 5.0.0.0/8 itself, all the more specifics of 30.0.0.0/8 that are of length 24 to 32 (like 30.9.9.96/28), and all the more specifics of the address prefixes in route set rs-foo. the range operators are giving precision π―
the mbrs-by-ref attribute is a list of maintainer names or the keyword ANY π«Ά if this attribute is used, 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's name. if the value of mbrs-by-ref is ANY, then any route object referring to the route set name is a member. and if mbrs-by-ref is missing, only the address prefixes listed in members are members of the set. the rules are so clear, I'm obsessed π
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 11: route-set objects.
Figure 11 shows example route-set objects that use mbrs-by-ref. the set rs-foo contains two address prefixes, 128.8.0.0/16 and 128.9.0.0/16, because those route objects refer to rs-foo in their member-of attribute. the set rs-bar contains 128.7.0.0/16 and 128.8.0.0/16. the 128.7.0.0/16 route is explicitly listed in rs-bar's members attribute, and the route object for 128.8.0.0/16 refers to rs-bar in its member-of attribute πΈ
one more thing, bestie: if an address prefix is listed in a route set's members attribute, it's a member of that set. the route object for that prefix does NOT need a member-of attribute pointing back at the set name. the member-of attribute of the route class is just an additional mechanism for specifying members indirectly β¨
5.2 as-set Class
okay so the as-set class is basically a group chat π the as-set attribute holds the name, which is an RPSL name that starts with as-, and members is the guest list, filled with AS numbers or other as-set names π«Ά here are the attributes in Figure 12:
Attribute Value Type
as-set <object-name> mandatory, single-valued,
class key
members list of <as-numbers> or optional, single-valued
<as-set-names>
mbrs-by-ref list of <mntner-names> optional, single-valued
Figure 12: as-set Class Attributes
Figure 13 has two as-set objects. as-foo contains two ASes, AS1 and AS2 π
then as-bar contains everyone in as-foo plus AS3, so that's AS1, AS2, AS3 β¨
as-set: as-foo as-set: as-bar
members: AS1, AS2 members: AS3, as-foo
Figure 13: as-set objects.
okay now the mbrs-by-ref attribute is where it gets spicy πΆοΈ it's a list of maintainer names or the keyword ANY. if it's used, 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, then literally any AS object that refers to the AS set is a member of it. and if mbrs-by-ref is missing, only the ASes listed in members get in. no bouncers, just the list π
Figure 14 shows an as-set that uses mbrs-by-ref. as-foo contains AS1, AS2 and AS3 π¦ AS4 is NOT in as-foo, even though its aut-num object references as-foo. the reason is that MNTR-OTHER isn't listed in the mbrs-by-ref attribute of as-foo. main character energy for MNTR-ME π
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 14: as-set objects.
5.3 Predefined Set Objects
okay so in any context that expects a route set (like the members attribute of the route-set class), an AS number ASx means the set of routes originated by ASx π§ and an as-set AS-X means the set of routes originated by the ASes inside 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 π
Figure 15 is the example. 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.
and then there are the big ones π the set rs-any contains all routes registered in IRR, and the set as-any contains all ASes registered in IRR π€―
5.4 Hierarchical Set Names
okay so set names can be hierarchical π a hierarchical set name is a sequence of set names and AS numbers separated by colons : β¨ these are all valid: AS1:AS-CUSTOMERS, AS1:RS-EXCEPTIONS, AS1:RS-EXPORT:AS2, RS-EXCEPTIONS:RS-BOGUS π
every component of a hierarchical set name that isn't an AS number should start with as- or rs-, for as sets and route sets respectively.
a set object named X1:...:Xn-1:Xn can only be created by the maintainer of the object named X1:...:Xn-1 π so only the maintainer of AS1 can create AS1:AS-FOO, and only the maintainer of AS1:AS-FOO can create AS1:AS-FOO:AS-BAR π«Ά
why is this so iconic? the whole point is to partition the set name space, so that whoever controls the set name X1 controls the entire set name space under X1, i.e. X1:...:Xn-1 π¦ this matters SO much because anyone can create a set named AS-MCI-CUSTOMERS, but only the people who created AS3561 can create AS3561:AS-CUSTOMERS π with the first one, it's not clear whether AS-MCI-CUSTOMERS has any relationship with MCI at all. with the second one, we can guarantee that AS3561:AS-CUSTOMERS and AS3561 were created by the same entity π
6 aut-num Class
ASes are specified with the aut-num class π· the attributes are in Figure 16. the aut-num value is the AS number of the AS that this object describes. the as-name attribute is a symbolic name (in RPSL name syntax) for the AS. and the import, export and default routing policies of the AS are specified with the import, export and default attributes, respectively π§
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, single-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 16: aut-num Class Attributes
6.1 import Attribute: Import Policy Specification
okay so Figure 17 is the topology we'll be using in all our examples in this section πΊοΈ there are three ASes (AS1, AS2, AS3), two exchange points (EX1 and EX2), and six routers π routers connected to the same exchange point peer with each other, meaning they open a connection to exchange routing information. each router exports a subset of the routes it has to its peer routers, and the peer routers import a subset of those π« while importing, a router can set some route attributes. for example, AS1 can assign higher preference values to the routes it imports from AS2 so that it prefers AS2 over AS3 π a router can also set route attributes while exporting, to affect route selection by its peers. for example, AS2 may set the MULTI-EXIT-DISCRIMINATOR BGP attribute so that AS1 prefers to use the router 9.9.9.2 π¦ most interAS policies come down to specifying which route subsets can be imported or exported, and how the various BGP route attributes are set and used π
---------------------- ----------------------
| 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 17: Example topology consisting of three ASes, AS1, AS2, and AS3; two exchange points, EX1 and EX2; and six routers.
okay so in RPSL, an import policy is split up into import policy expressions π§© each one is specified 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 π the meaning of an import attribute goes like this: 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 }
this example says the route 128.9.0.0/16 is accepted from AS2 with preference 1 π«Ά in the next few subsections we'll go over how peerings, actions and filters are specified π§
6.1.1 Peering Specification
our example above used an AS number to specify peerings π but peerings can be specified at different granularities. the first form of a peering specification looks like this:
<peer-as> [<peer-router>] [at <local-router>]
where <local-router> and <peer-router> are IP addresses of routers, and <peer-as> is an AS number. <peer-as> must be the AS number of <peer-router> π both <local-router> and <peer-router> are optional. if both are specified, the peering specification identifies only the peering between those two routers π if only <local-router> is specified, it identifies all the peerings between <local-router> and any of its peer routers in <peer-as> β¨ if only <peer-router> is specified, it identifies all the peerings between any router in the local AS and <peer-router> π¦ and if neither is specified, it identifies all the peerings between any router in the local AS and any router in <peer-as> π
okay examples time π using Figure 17, 7.7.7.1, 7.7.7.2 and 7.7.7.3 peer with each other, and 9.9.9.1, 9.9.9.2 and 9.9.9.3 peer with each other. in this 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 }
and 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 }
the second form of a <peering> specification looks like this:
<as-expression> [at <router-expression>]
where <as-expression> is an expression over AS numbers and sets using the operators AND, OR, and NOT, and <router-expression> is an expression over router IP addresses and DNS names using the operators AND, OR, and NOT π a DNS name can only be used if there's an inet-rtr object for that name that binds the name to IP addresses π this form identifies all the peerings between any local router in <router-expression> and any of their peer routers in the ASes in <as-expression>. if <router-expression> isn't specified, it defaults to all routers of the local AS π
in this example, 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 }
and in this last 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 works out because "AS-FOO and not AS2" equals AS3, and "not 7.7.7.1" equals 9.9.9.1 π¦
6.1.2 Action Specification β¨
okay so policy actions in RPSL either set or modify route attributes π like giving a route a preference, adding a BGP community to the community path attribute, or setting the MULTI-EXIT-DISCRIMINATOR attribute π they can also tell routers to do special stuff, 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 the list. every action ends with the character ; π you can also stack actions one after another to make a composite policy action, and those 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, then med to 0, then appends 10250 and {3561,10} to the community path attribute πΈ literally so clean π
6.1.3 Filter Specification π§
a policy filter is a logical expression π₯ you hand it a set of routes and it gives you back a subset of them, and we say the filter matches that subset π filters can match routes using any path attribute, like the destination address prefix (aka NLRI), the AS-path, or the community attributes β¨
filters can be composite using the operators AND, OR, and NOT π these are the filters you can use to pick out a subset of routes:
ANY π the filter keyword ANY matches all routes, no cap
Address-Prefix Set π this is an explicit list of address prefixes wrapped in braces { and }. the filter matches the routes whose destination address-prefix is in the set π examples:
{ 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 (^-, ^+, ^n, or ^n-m) π¦ for example, this set:
{ 5.0.0.0/8^+, 128.9.0.0/16^-, 30.0.0.0/8^16, 30.0.0.0/8^24-32 }
is giving all the more specifics of 5.0.0.0/8, including 5.0.0.0/8 itself π plus all the more specifics of 128.9.0.0/16 excluding 128.9.0.0/16 π ββοΈ, plus the more specifics of 30.0.0.0/8 that are length 16 (like 30.9.0.0/16), plus the more specifics of 30.0.0.0/8 that are length 24 to 32 (like 30.9.9.96/28) π
Route Set Name πΈ a route set name matches the routes that belong to that 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 the deets). examples:
aut-num: AS1
import: from AS2 action pref = 1; accept AS2
import: from AS2 action pref = 1; accept AS-FOO
import: from AS2 action pref = 1; accept RS-FOO
the keyword PeerAS can be used instead of the peer's AS number π§‘ this is super useful when the peering is set up with an AS expression. like:
as-set: AS-FOO
members: AS2, AS3
aut-num: AS1
import: from AS-FOO action pref = 1; accept PeerAS
is the same as:
aut-num: AS1
import: from AS2 action pref = 1; accept AS2
import: from AS3 action pref = 1; accept AS3
a route set name can also be followed by one of the operators ^-, ^+, ^n or ^n-m πͺ these operators are distributive over the route sets. so { 5.0.0.0/8, 6.0.0.0/8 }^+ equals { 5.0.0.0/8^+, 6.0.0.0/8^+ }, and AS1^- gives you all the exclusive more specifics of routes originated by AS1 ππ«Ά
AS Path Regular Expressions π€οΈ you can use an AS-path regular expression as a filter by wrapping it in < and > π an AS-path filter matches the routes that traverse a sequence of ASes matched by that regex π
a router can check this using the AS_PATH attribute in the Border Gateway Protocol [18], or the RD_PATH attribute in the Inter-Domain Routing Protocol[17] π
AS-path regular expressions are POSIX compliant regexes over the alphabet of AS numbers π§ the constructs are:
ASN where ASN is an AS number. ASN matches the AS-path
that is of length 1 and contains the corresponding AS
number (e.g. AS-path regular expression AS1 matches the
AS-path "1").
The keyword PeerAS can be used instead of the AS number
of the peer AS.
AS-set where AS-set is an AS set name. AS-set matches the AS-paths
that is 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 AS numbers 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
which 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 regex operators, listed in decreasing order of evaluation π they're all left associative, so they run left to right π«Ά
Unary postfix operators * + ? {m} {m,n} {m,} π for a regex A, A* matches zero or more occurrences of A, A+ matches one or more, A? matches zero or one, A{m} matches exactly m occurrences, A{m,n} matches m to n occurrences, and A{m,} matches m or more occurrences. for example, [AS1 AS2]{2} matches AS1 AS1, AS1 AS2, AS2 AS1, and AS2 AS2 π
Unary postfix operators ~* ~+ ~{m} ~{m,n} ~{m,} π¦ these work like the ones above, but every occurrence of the regex has 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 implicit, and it sits between two regexes A and B when no other explicit operator is specified. A B matches an AS-path if A matches some prefix of the AS-path and B matches the rest of it πΈ
Binary alternative (or) operator | π for regexes A and B, A | B matches any AS-path matched by A or B β¨
parentheses can override the default order of evaluation π and whitespace can be used to make things more readable π«§
here are some AS-path filter examples:
<AS3>
<^AS1>
<AS2$>
<^AS1 AS2 AS3$>
<^AS1 .* AS2$>
the first 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 build composite policy filters:
NOT π
ββοΈ given a policy filter x, NOT x matches the routes that are not matched by x. so it's the negation of filter x π«Ά
AND π₯ given two policy filters x and y, x AND y matches the intersection of the routes matched by x and the routes matched by y π
OR πΈ given two policy filters x and y, x OR y matches the union of the routes matched by x and the routes matched by y π¦
heads up: the OR operator can be implicit, so x y is equivalent to x OR y β¨ examples:
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 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 compare against the values of other attributes π the attributes you can use in filters are in the RPSL dictionary, so see Section 7 for details. here's an example using the BGP community attribute:
aut-num: AS1
export: to AS2 announce AS1 AND NOT community.contains(NO_EXPORT)
filters that use the routing policy attributes from the dictionary are evaluated before the AND, OR, and NOT operators get evaluated π«Άπ
6.1.4 Example Policy Expressions π
aut-num: AS1
import: from AS2 action pref = 1;
from AS3 action pref = 2;
accept AS4
this one says AS4's routes are accepted from AS2 with preference 1, and from AS3 with preference 2 πΈ lower integer preference values are preferred over higher ones, so AS2 wins here π
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
this one 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 π¦
same energy here: an export policy expression is specified with the export attribute π its syntax is:
export: to <peering-1> [action <action-1>]
. . .
to <peering-N> [action <action-N>]
announce <filter>
the action specification is optional π«§ the semantics go like this: the routes matched by <filter> get exported to all the peers listed in <peerings>, and while exporting routes at <peering-M>, <action-M> gets executed π
example:
aut-num: AS1
export: to AS2 action med = 5; community .= 70;
announce AS4
here AS4's routes are announced to AS2 with the med attribute's value set to 5, and community 70 added to the community list π
another example πΈ:
aut-num: AS1
export: to AS-FOO announce ANY
in this one, 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 bestie, 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 π¦ or inject routes from one protocol into another, or set up multi-protocol policies π. The valid protocol names live in the dictionary. <protocol-1> is the protocol whose routes are getting swapped around, and <protocol-2> is the protocol that receives them. If you leave either one out, both default to the Internet Exterior Gateway Protocol, which is currently BGP π.
in this example, every interAS route gets injected into RIP πΈ
aut-num: AS1
import: from AS2 accept AS2
export: protocol BGP4 into RIP
to AS1 announce ANY
in this one, AS1 accepts AS2's routes plus any more-specifics of AS2's routes, but it does not inject those extra more-specific routes into OSPF π
aut-num: AS1
import: from AS2 accept AS2^+
export: protocol BGP4 into OSPF
to AS1 announce AS2
here AS1 pushes its static routes (anything in the set AS1:RS-STATIC-ROUTES) into the interAS protocol and prepends AS1 twice to their AS paths π§
aut-num: AS1
import: protocol STATIC into BGP4
from AS1 action aspath.prepend(AS1, AS1);
accept AS1:RS-STATIC-ROUTES
and in this last one, 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
okay so it's possible for the same peering to be covered by more than one peering specification in a policy expression π. Like this:
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
this isn't an error, but it's definitely not desirable π. To break the tie, the action from the first peering specification is the one that gets used, so the routes are accepted with preference 2. We call this the specification-order rule π.
now check this one out π:
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 specifications cover the peering 7.7.7.1-7.7.7.2, but the second one covers it more specifically. The specification-order rule still applies, so only pref = 2 runs. The second peering-action pair is totally useless here, because the first pair always covers it first π. If you actually wanted preference 1 on that one peering and preference 2everywhere 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 for 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. 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 β¨.
for the RPSL implementors out there π«Ά, here's the general specification-order rule. Take 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
these are equivalent to the following 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
so peerings-3 is the stuff covered by both peerings-1 and peerings-2, and peerings-4 is the stuff covered by peerings-2 but not by peerings-1. And filter-2 AND NOT filter-1 just 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}
so we've got 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 gets accepted with preference 2, and 75.0.0.0/8 gets accepted with preference 1. The peering 9.9.9.1-9.9.9.2 is only covered by the second expression, so both 128.9.0.0/16 and 75.0.0.0/8 are accepted there with preference 1 π.
the same ambiguity resolution rules also apply to export and default policy expressions π .
6.5 default Attribute: Default Policy Specification
default routing policies are set up with the default attribute π. Its syntax looks like this:
default: to <peering> [action <action>] [networks <filter>]
the <action> and <filter> parts are optional. Here's how it works: the <peering> says which AS (and which router, if you include one) you're defaulting to. The <action>, if you include it, sets things like a relative preference when you have multiple defaults. The <filter>, if you include it, is a policy filter, and a router picks its default router from the routes in its routing table that match this <filter> π«Ά.
in this example, AS1 defaults to AS2 for routing πΈ:
aut-num: AS1
default: to AS2
here, 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
in this one, AS1 defaults to both AS2 and AS3, but prefers AS2 over AS3 π:
aut-num: AS1
default: to AS2 action pref = 1;
default: to AS3 action pref = 2;
and last but not least, 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 π but honestly? we only recommend structured policies to advanced RPSL users. if you're newer to this, feel free to skip this section, no shame at all π«Ά
here's the syntax for a structured policy specification π :
<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>
quick heads up π there's a semicolon at the end of an <import-factor>. if the policy isn't structured (like every example in the other sections), that semicolon is optional. and the syntax and semantics of an <import-factor> were already covered 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>. its meaning is the union of those <import-factor>'s, using the specification order rule π
an <import-expression> is either one <import-term> on its own, or an <import-term> followed by the keyword "except" or "refine", followed by another <import-expression>. and yes, this allows nesting π so you can get exceptions to exceptions, refinements to refinements, or even refinements to exceptions, and so on and so forth. it's giving Inception energy π
now the except operator π the result of an except operation is another <import-term>. the resulting policy set holds the policies from the right hand side, but their filters get modified so they only include routes that are also matched by the left hand side. then the left hand side's policies get added afterwards, and their filters get modified to exclude any routes matched by the right hand side. the filters are the only thing that changes here. the actions get copied verbatim, no edits π«Ά and when you've got multiple levels of nesting, the operations (both except and refine) are performed right to left. main character behavior π
check out 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};
}
}
so the route 128.9.0.0/16 is originated by AS226, and AS226 is a member of the as set as-foo π¦ in this example, 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. the whole thing is so iconic π
we can get the same answer using the algebra from above too π§ let's 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};
}
which 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});
}
and since AS226 is in as-foo and 128.9.0.0/16 is in AS226, it simplifies down 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;
}
π now the refine operator! the resulting set comes from taking the cartesian product of the two sides, like this: for each policy l on the left hand side and each policy r on the right hand side, the resulting policy's peerings are the peerings common to both r and l. 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 comes out empty, no resulting policy gets generated. bye bye π
here's an example for that πΈ
import: { from AS-ANY action pref = 1;
accept community.contains({3560,10});
from AS-ANY action pref = 2;
accept community.contains({3560,20});
} refine {
from AS1 accept AS1;
from AS2 accept AS2;
from AS3 accept AS3;
}
so any route with community {3560,10} gets a preference of 1, and any route with community {3560,20} gets a preference of 2, no matter who they're imported from π but only AS1's routes come in from AS1, only AS2's routes come in from AS2, only AS3's routes come in from AS3, and no routes at all come in from any other AS. we can reach the same conclusion with the algebra above too! so our example is equivalent to:
import: {
from AS1 action pref = 1;
accept community.contains({3560,10}) AND AS1;
from AS1 action pref = 2;
accept community.contains({3560,20}) AND AS1;
from AS2 action pref = 1;
accept community.contains({3560,10}) AND AS2;
from AS2 action pref = 2;
accept community.contains({3560,20}) AND AS2;
from AS3 action pref = 1;
accept community.contains({3560,10}) AND AS3;
from AS3 action pref = 2;
accept community.contains({3560,20}) AND AS3;
}
π note that the common peerings between "from AS1" and "from AS-ANY" are the peerings in "from AS1". we never formally define "common peerings", but it's pretty straightforward to figure out the definition from the definitions of peerings (see Section 6.1.1 β¨).
one more example, and this one is a vibe π¦
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;
}
here only routes of length 0 to 18 get accepted, and med's value is set to 0 to disable med's effect for all peerings. 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 other peerings π this is 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 last but not least: the above syntax and semantics also apply equally to structured export policies! just swap "from" for "to" and "accept" for "announce" and you're golden π«Ά
7. dictionary Class β¨
okay bestie, the dictionary class is basically RPSL's extensibility superpower π¦ It defines routing policy attributes, types, and routing protocols. rp-attributes (we'll call them rp-attributes from here on π ) can match real protocol attributes like the BGP path attributes (community, dpa, and AS-path), or they can be router features like BGP route flap damping πΈ Whenever a new protocol, protocol attribute, or router feature shows up, the dictionary object gets updated with the right rp-attribute and protocol definitions. so iconic, right? π
An rp-attribute is an abstract class, which means there's no data representation you can poke at 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 attributes. Access methods can take arguments, and those arguments are strongly typed. the prepend method takes AS numbers as its argument, so no sneaking in random stuff π
Once an rp-attribute is defined in the dictionary, it can be used 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. They're also allowed to approximate policy analyses on rp-attributes they don't understand: a filter method may always match, and an action method may always perform no-operation. Analysis tools may even download code to perform appropriate operations, using mechanisms outside the scope of RPSL. the way that's giving "I'll figure it out myself" energy π
Now the fun part, the syntax and semantics of the dictionary class. Honestly this part isn't essential for reading dictionary objects, but it's essential for creating one π If you just want the good stuff, feel free to skip ahead to the RPSL Initial Dictionary subsection (Section 7.1) π
The attributes of the dictionary class are shown in Figure 18 π The dictionary attribute is the name of the dictionary object, and it has to follow the RPSL naming rules. There can be many dictionary objects, but there is always one well-known dictionary object called "RPSL", and all tools use it by default π
The rp-attribute attribute has the following syntax:
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 18: dictionary Class Attributes π
rp-attribute: <name>
<method-1>(<type-1-1>, ..., <type-1-N1> [, "..."])
...
<method-M>(<type-M-1>, ..., <type-M-NM> [, "..."])
where <name> is the name of the rp-attribute, and <method-i> is the name of an access method for the rp-attribute, taking Ni arguments where the j-th argument is of type <type-i-j>. A method name is either an RPSL name or one of the operators defined in Figure 19. The operator methods, with the exception of operator() and operator[], can take only one argument π₯
operator= operator==
operator<<= operator<
operator>>= operator>
operator+= operator>=
operator-= operator<=
operator*= operator!=
operator/= operator()
operator.= operator[]
Figure 19: Operators π
An rp-attribute can have many methods defined for it. Some methods may even share a name, as long as their arguments are of different types π¦ If the argument list is followed by "...", 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 β¨ An argument's type can be one of the predefined types or one of the dictionary defined types. The predefined type names are listed in Figure 20. The integer and real types can be followed by a lower and an upper bound to specify the set of valid values for the argument, and that 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 take the values 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 π
integer[lower, upper] as_number
real[lower, upper] ipv4_address
enum[name, name, ...] address_prefix
string address_prefix_range
boolean dns_name
rpsl_word filter
free_text as_set_name
email route_set_name
Figure 20: Predefined Types πΈ
The typedef attribute specifies a dictionary defined type. Its syntax is as follows:
typedef: <name> union <type-1>, ... , <type-N>
| <name> list [<min_elems>:<max_elems>] of <type>
where <name> is the name of the type being defined, and <type-M> is another type name, either predefined or dictionary defined. In the first form, the defined type is any one of <type-1> through <type-N> (analogous to unions in C[12]) π§ In the second form, the defined type is a list type where 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, and if you leave it out there is no restriction on the number of list elements. A value of a list type is represented as a sequence of elements separated by the character "," and enclosed by the characters "{" and "}" π
A protocol attribute of the dictionary class defines a protocol and a set of peering options for that protocol (which are used in the inet-rtr class in Section 9). Its syntax is as follows:
protocol: <name>
MANDATORY | OPTIONAL <option-1>(<type-1-1>, ...,
<type-1-N1> [, "..."])
...
MANDATORY | OPTIONAL <option-M>(<type-M-1>, ...,
<type-M-NM> [, "..."])
where <name> is the name of the protocol, MANDATORY and OPTIONAL are keywords, and <option-i> is a peering option for this protocol, taking Ni many arguments. The syntax and semantics of the arguments are the same as for the rp-attribute. If the keyword MANDATORY is used, the option is mandatory and needs to be specified for each peering of this protocol. If the keyword OPTIONAL is used, the option can be skipped π«Ά
7.1. Initial RPSL Dictionary and Example Policy Actions and Filters
Here's the starter dictionary, and honestly it's a whole vibe π It defines the RPSL dictionary with pref, med, dpa, aspath, community, next-hop, and cost rp-attributes, plus the BGP4 protocol and a bunch of placeholder protocols. Time to see it in action π
dictionary: RPSL
rp-attribute: # preference, smaller values represent higher preferences
pref
operator=(integer[0, 65535])
rp-attribute: # BGP multi_exit_discriminator attribute
med
operator=(integer[0, 65535])
# to set med to the IGP metric: med = igp_cost;
operator=(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
# - internet, no_export, no_advertise (see RFC-1997)
# - two 2-byte integers to be concatanated eg. {3561,70}
community_elm union
integer[1, 4294967200],
enum[internet, no_export, no_advertise],
list[2:2] of integer[0, 65535]
typedef: # list of community values { 40, no_export, {3561,70}}
community_list
list of community_elm
rp-attribute: # BGP community attribute
community
# set to a list of communities
operator=(community_list)
# order independent equality comparison
operator==(community_list)
# append community values
operator.=(community_elm)
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, ...)
rp-attribute: # next hop router in a static route
next-hop
operator=(ipv4_address) # a router address
operator=(enum[self]) # router's own address
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 21: RPSL Dictionary
okay so Figure 21 shows the initial RPSL dictionary π it has seven rp-attributes:
prefassigns local preference to the routes accepted πmedassigns a value to the MULTI_EXIT_DISCRIMINATOR BGP attribute πΈdpaassigns a value to the DPA BGP attribute β¨aspathprepends a value to the AS_PATH BGP attribute π¦communityassigns a value to, or checks the value of, the community BGP attribute πnext-hopassigns next hop routers to static routes πcostassigns 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 no_export or no_advertise (defined in [7]), or a list of two 2-byte unsigned integers. in that last case the two integers get concatenated into one 4-byte integer π₯ (this last form is super common on the Internet for partitioning the community number space. a provider uses its AS number as the first two bytes and assigns whatever semantics it wants to the last two bytes, iykyk π)
the initial dictionary (Figure 21) only defines options for the Border Gateway Protocol: asno and flap_damp π the mandatory asno option is the AS number of the peer router. the optional flap_damp option tells the router to damp route flaps[19] when importing routes from the peer router π
flap_damp can be used with or without parameters. if you leave the parameters out, they default to:
flap_damp(1000, 2000, 750, 900, 900, 20000)
so here's the tea β each route flap adds a penalty of 1000, and the route gets suppressed once the penalty hits 2000. the penalty gets 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 max penalty a route can rack up is 20,000, which means the max suppress time after a route becomes stable is about 75 minutes β³ these defaults match the default flap damping parameters in several routers, so it's giving consistency π
Policy Actions and Filters Using RP-Attributes
okay now the syntax π§ a policy action or filter using an rp-attribute x looks like this:
x.method(arguments)
x "op" argument
method is a method, and "op" is an operator method of the rp-attribute x. if you use an operator method in a composite policy filter, it evaluates earlier than 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 can be assigned either a positive integer or the word "igp_cost" π
med = 0;
med = igp_cost;
the dpa rp-attribute can be assigned a positive integer π
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, you get a 4-byte integer where the more significant two bytes equal 3561 and the less significant two bytes equal 10 π¦ and here's how you delete communities from the community rp-attribute π«Ά
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 contains 100, NO_EXPORT, {3561,10}, and 200. in the latter case, the community rp-attribute gets cleared π§Ή and you can compare it against a list of communities too π
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);
the following examples are INVALID, so don't even try them bestie π ββοΈ
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 22 is a more advanced example using the community rp-attribute, and it's honestly iconic π in this example, AS3561 bases its route selection preference on the community attribute. other ASes can indirectly affect AS3561's route selection by including the appropriate communities in their route announcements π¦
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.contains({3561,90})
import: from AS3561:AS-PEERS
action pref = 20;
accept community.contains({3561,80})
import: from AS3561:AS-PEERS
action pref = 20;
accept community.contains({3561,70})
import: from AS3561:AS-PEERS
action pref = 0;
accept ANY
Figure 22: Policy example using the community rp-attribute.
8 Advanced route Class π
8.1 Specifying Aggregate Routes β¨
okay bestie, this part is all about how you tell routers to build an aggregate route π¦. Five attributes do the heavy lifting here: aggr-bndry, aggr-mtd, export-comps, inject, and holes [9]. A route object counts as an aggregate if any of them is specified, except inject, which doesn't count on its own. The origin for an aggregate is the AS doing the aggregating, the aggregator AS π
. In this section we use three words. "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 fed into those path attributes πΈ.
The components attribute decides which component routes form the aggregate. Its syntax goes like this:
components: [ATOMIC] [[protocol <protocol>] <filter>
[protocol <protocol> <filter> ...]]
Here <protocol> is a routing protocol name like BGP, OSPF or RIP (valid names live in the dictionary), and <filter> is a policy expression. Routes that match one of the filters and were learned from the matching protocol are used to form the aggregate. If you leave out <protocol>, it defaults to any protocol. The <filter> secretly carries an "AND" term with the more specifics of the aggregate, so only component routes get picked π. If you use the ATOMIC keyword, the aggregation is done atomically [9]. No filter? It defaults to more specifics. And if the components attribute is missing completely, all more specifics without the ATOMIC keyword get used β¨.
route: 128.8.0.0/15
origin: AS1
components: <^AS2>
route: 128.8.0.0/15
origin: AS1
components: protocol BGP {128.8.0.0/16^+}
protocol OSPF {128.9.0.0/16^+}
Figure 23: Two aggregate route objects.
Figure 23 has two route objects. The first one aggregates more specifics of 128.8.0.0/15 whose AS paths start with AS2 π. The second one aggregates some routes learned from BGP plus some learned from OSPF π§.
The aggr-bndry attribute is an expression over AS numbers and sets, using the operators AND, OR, and NOT. Whatever it works out to is the set of ASes that form the aggregation boundary π. If aggr-bndry is missing, the origin AS is the only boundary. Outside that boundary, only the aggregate gets exported and the more specifics get suppressed π. Inside the boundary? The more specifics are exchanged too, so it's a whole vibe π.
The aggr-mtd attribute says how the aggregate gets generated. Here's the syntax:
aggr-mtd: inbound
| outbound [<as-expression>]
<as-expression> is an expression over AS numbers and sets, again with AND, OR, and NOT. If it's missing, it defaults to AS-ANY. With outbound aggregation, the more specifics stay within the AS, and the aggregate gets formed at every inter-AS boundary with ASes in <as-expression> before it's exported. The one exception is ASes inside the aggregating boundary, because aggr-bndry is enforced no matter what <as-expression> says π«Ά. With inbound aggregation, the aggregate is formed at all inter-AS boundaries before routes are imported into the aggregator AS. Also, you can't put an <as-expression> on inbound aggregation, so don't even try π
ββοΈ. If aggr-mtd is missing completely, it defaults to outbound AS-ANY π
.
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 24: Outbound multi-AS aggregation example.
Figure 24 is an outbound aggregation example. AS1 and AS2 team up, announce only the less specific 128.8.0.0/15 to the outside world, and swap more specifics between themselves π€. This is super useful when some components live in AS1 and others live in AS2 π.
When a set of routes gets aggregated, the goal is to export only the aggregate and keep the more specifics from leaking outside the aggregation boundary π. But sometimes policy and topology need an exception, like a multi-homed component, so you end up exporting some components anyway π. The export-comps attribute holds an RPSL filter that matches the more specifics you want to export outside the boundary. If it's missing, more specifics don't leave the boundary at all. Also, the export-comps filter has an implicit "AND" with the more specifics of the aggregate, so it's always working inside that group π₯.
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 25: Outbound aggregation with export exception.
Figure 25 shows another outbound aggregation, this time with an exception. 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 connected to AS1 and some other AS π.
The inject attribute says which routers perform the aggregation and when. Its syntax is:
inject: [at <router-expression>] ...
[action <action>]
[upon <condition>]
Here <action> is an action specification (see Section 6.1.2), <condition> is a boolean expression (more on that below), and <router-expression> is an expression over router IP addresses and DNS names, using AND, OR, and NOT. A DNS name only works if there's an inet-rtr object that binds that name to IP addresses π§ .
Every router in <router-expression> and in the aggregator AS performs 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. The aggregate only gets generated if and only if this condition is true β¨. The <condition> uses the logical operators AND and OR (NOT isn't allowed here) over these three things:
HAVE-COMPONENTS { list of prefixes }
EXCLUDE { list of prefixes }
STATIC
HAVE-COMPONENTS can only list 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 include prefix ranges (using ^-, ^+, ^n, and ^n-m). In that case, at least one prefix from each range needs to be in the routing table for the condition to be true π―. EXCLUDE can list any prefixes at all. 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 π. If there's no upon clause at all, the aggregate gets generated if and only if there's a component in the routing table (meaning a more specific that matches the filter in the components attribute) π«§.
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 26: Examples of inject.
Figure 26 has two examples πΈ. In the first one, the aggregate gets injected at two routers, and each one sets the dpa path attribute to a different value. In the second one, the aggregate only gets generated if both 128.8.0.0/16 and 128.9.0.0/16 are in the routing table. The first example only needed one of them to be present, so the second one is way stricter π.
The holes attribute lists the component address prefixes that can't be reached through the aggregate route. Maybe that chunk of address space just isn't allocated π§©. holes is handy for diagnosis. In Figure 26, the second example has a hole, 128.8.8.0/24. That could happen when a customer switches providers and takes that piece of address space with them π¦.
8.1.1 Interaction with policies in aut-num class
8.1.1 Interaction with policies in aut-num class
Okay, here's where the policies come in π. An aggregate that gets formed is only announced to other ASes if the AS's export policies allow exporting the aggregate. When an aggregate is formed, the more specifics are suppressed from export, except for ASes in aggr-bndry and except for the components listed in export-comps. For those exceptions to actually happen, the AS's export policies have to explicitly allow them too π
.
If an aggregate isn't formed (because of the upon clause), then the more specifics of the aggregate can be exported to other ASes, but only if the AS's export policies allow it π. Basically, before any route (aggregate or more specific) gets exported, it gets filtered twice: once based on the route objects, and once based on the AS's export policies π.
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 27: Interaction with policies in aut-num class.
Figure 27 is an interaction example π§. 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, which is 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 be formed if both components are available. In that case, only the aggregate gets announced to AS4 and AS5. But if one component is missing, the aggregate doesn't get formed, and any available component or more specific gets exported to AS4 and AS5 instead π« . Whether or not aggregation happens, only the more specifics go to AS6, since it isn't listed in aggr-mtd πΈ.
When you're doing inbound aggregation, configuration generators may eliminate the aggregation statements on routers where the AS's import policy prohibits importing any more specifics π§Ή.
8.1.2 Ambiguity resolution with overlapping aggregates πΈ
Okay so, what happens when you've got several aggregate routes and they overlap? π Like, one is less specific than the other? Then they have to be evaluated from most specific to least specific, bestie. π
Every time an aggregation happens, the aggregate and whatever's listed in export-comps become ingredients for the next, less specific aggregate. Anything NOT in export-comps is just not available, sorry not sorry π. A route is exportable to an AS if it's the least specific aggregate exportable to that AS, OR it's listed in the export-comps of an exportable route. It's a recursive definition, so it's giving main character energy π¦β¨
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 28: Overlapping aggregations.
So in Figure 28, 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 altogether? They squish all four routes into 128.8.0.0/14 π₯
Now let's look at AS4, assuming all four components are available. A router in AS1 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. The router then generates 128.8.0.0/14 from those three routes. So for AS4, 128.8.0.0/14 is exportable, along with its exception 128.10.0.0/15 and that exception's exception 128.11.0.0/16. Iconic layering π
For AS2, a router in AS1 only generates 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 exportable too, because they didn't take part in any aggregate that was exportable to AS2 π
And for AS3? A router in AS1 only generates 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 π§
The inject attribute can be used to specify static routes by using "upon static" as the condition, which is so useful when you just want to hardcode things π
inject: [at <router>] ...
[action <action>]
upon static
Here, the <router> executes the <action> and injects 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. This route has two next-hop routers, 7.7.7.2 and 7.7.7.3. It has a cost of 10 over 7.7.7.2 and 20 over 7.7.7.3. Two paths, one route, very organized π«Ά
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 π¦
Routers get specified using the inet-rtr class, and the attributes of that class are shown in Figure 29 β¨ The inet-rtr attribute is a valid DNS name of the router being described. Each alias attribute, if it's there, is a canonical DNS name for the router. The local-as attribute tells you 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
Figure 29: 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 add an action to set other parameters for that interface π
Figure 30 shows an example inet-rtr object. The router is named "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 specified 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 30: 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>
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>. 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 π
10. Security Considerations π
Okay, serious moment, bestie π 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. 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. Please do not skip this part, it's literally the most important bit π
11. Acknowledgements π«Ά
We'd like to thank Jessica Yu, Randy Bush, Alan Barrett, David Kessens, 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, and the participants of the IETF RPS Working Group for their various comments and suggestions. You all are literally the best πβ¨
References π
[1] Internet Routing Registry. Procedures.
http://www.ra.net/RADB.tools.docs/,
http://www.ripe.net/db/doc.html.
[2] Alaettinouglu, C., Meyer, D., and J. Schmitz, "Application of
Routing Policy Specification Language (RPSL) on the Internet",
Work in Progress.
[3] T. Bates. Specifying an `Internet Router' in the Routing
Registry. Technical Report RIPE-122, RIPE, RIPE NCC, Amsterdam,
Netherlands, October 1994.
[4] 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.
[5] 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.
[6] 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.
[7] Chandra, R., Traina, P., and T. Li, "BGP Communities Attribute,"
RFC 1997, August 1996.
[8] Crocker, D., "Standard for the format of ARPA Internet text
messages, STD 11, RFC 822, August 1982.
[9] V. Fuller, T. Li, J. Yu, and K. Varadhan. Classless Inter-
Domain Routing (CIDR): an Address Assignment and Aggregation
Strategy, 1993.
[10] 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.
[11] 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.
[12] B. W. Kernighan and D. M. Ritchie. The C Programming
Language. Prentice-Hall, 1978.
[13] Kessens, D., Woeber, W., and D. Conrad, "RIDE referencing",
Work in Progress.
[14] A. Lord and M. Terpstra. RIPE Database Template for
Networks and Persons. Technical Report ripe-119, RIPE, RIPE
NCC, Amsterdam, Netherlands, October 1994.
[15] A. M. R. Magee. RIPE NCC Database Documentation. Technical
Report RIPE-157, RIPE, RIPE NCC, Amsterdam, Netherlands, May
1997.
[16] Mockapetris, P., "Domain names - concepts and facilities,"
STD 13, RFC 1034, November 1987.
[17] Y. Rekhter. Inter-Domain Routing Protocol (IDRP). Journal
of Internetworking Research and Experience, 4:61--80, 1993.
[18] Rekhter, Y., and T. Li, "A Border Gateway Protocol 4 (BGP-4),"
RFC 1771, March 1995.
[19] Villamizar, C., Chandra, R., and R. Govindan, "BGP Route
Flap Damping", Work in Progress.
A. Routing Registry Sites π
The routing registries as of November 1996 are RIPE, RADB, CANet, MCI and ANS. You can contact any one of these registries to find out the current list of registries, which is a very good use of your afternoon π
B. Authors' Addresses π
Cengiz Alaettinoglu
USC Information Sciences Institute
4676 Admiralty Way, Suite 1001
Marina del Rey, CA 90292
EMail: cengiz@isi.edu
Tony Bates
Cisco Systems, Inc.
170 West Tasman Drive
San Jose, CA 95134
EMail: tbates@cisco.com
Elise Gerich
At Home Network
385 Ravendale Drive
Mountain View, CA 94043
EMail: epg@home.net
Daniel Karrenberg
RIPE Network Coordination Centre (NCC)
Kruislaan 409
NL-1098 SJ Amsterdam
Netherlands
EMail: dfk@ripe.net
David Meyer
University of Oregon
Eugene, OR 97403
EMail: meyer@antc.uoregon.edu
Marten Terpstra
c/o Bay Networks, Inc.
2 Federal St
Billerica MA 01821
EMail: marten@BayNetworks.com
Curtis Villamizar
ANS
EMail: curtis@ans.net
C. Full Copyright Statement β¨
Copyright (C) The Internet Society (1998). All Rights Reserved. π
okay so the big copyright vibe here is that you can totally share this doc and translations of it π You can also make derivative works that comment on or explain it, or help people actually implement it, and you can publish and distribute those too, in whole or in part, with no restrictions of any kind π¦ The one tiny catch is that the copyright notice and this paragraph have to stay on all of those copies and derivative works π«Ά
BUT (and this is a big but π) the original document itself may not be modified in any way. You can't remove the copyright notice, and you can't remove the references to the Internet Society or other Internet organizations. There are two exceptions: you can change it for developing Internet standards, in which case the copyright procedures in the Internet Standards process must be followed π, or you can change it to translate it into languages other than English π
The limited permissions above are perpetual, and the Internet Society or its successors or assigns will never 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, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. π
π¦ where this page comes from
- ietf: rfc2280 1998-01
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms