Most large ISP and enterprise networks deploy routers from different vendors. They leverage standardized routing protocols such as BGP to ensure that the control plane of their different routers interoperates.
Unfortunately, standardized protocols do not always evolve quickly enough to meet the needs of operators who need to deploy new services. It can take several years to document, standardize, implement, and then deploy a new BGP feature. Furthermore, many of the features requested by network operators are never standardized and thus cannot be used.
xBGP proposes a paradigm shift, enabling network operators to customize the routing protocols deployed in their network.
First, all xBGP-compliant implementations include a vendor-neutral API that exposes the internals of the BGP datastructures and functions, allowing network operators to implement new features on top of the existing BGP implementations.
READ: BGP in 2020 – The BGP Table
Second, all xBGP-compliant routers include a modified eBPF virtual machine. Thanks to this virtual machine, network operators can write their BGP extension once and run it on any xBGP-compliant router in their network. This brings network programmability in the control plane.
Our approach allows extending, in a relatively easy way, different BGP implementations without having to convince the different vendors of the benefits of the proposed modification.
How can we add a new feature with xBGP ?
The basics of BGP are defined in RFC4271. Every BGP implementation must adhere to this document to be able to establish a session with a router running a different BGP implementation. From this RFC, a simple BGP workflow can be depicted:
- BGP messages are received by the router
- If the message is a BGP UPDATE, it is first checked on the importation side of the router. If the route passes the import policies, it is installed in a special data-structure called Adj-RIB-in
- If the route is accepted, then it is copied in the Loc-RIB. This datastructure contains all accepted routes from neighbouring BGP speakers
- The BGP decision process is run for every route contained in the Loc-RIB.After this step, one BGP Route is selected towards each prefix known by the router
- The accepted routes are then inserted in the Adj-RIB-out. Before sending the best BGP route to its neighbours, each route must pass the export filters
A feature such as Route Reflector requires modifications to the whole BGP workflow to be implemented. Indeed, RFC4456 defines two new BGP attributes, the ORIGINATOR_ID and the CLUSTER_LIST. It also modifies the BGP decision process, and export and import filters, to prevent routing message loops.
xBGP uses this BGP workflow to place insertion points. Insertion points are the locations of the BGP implementation where the operator-provided bytecode can be executed. xBGP defines the five insertion points depicted in Figure 2:
The following list explains the role of these insertion points with an example of how to implement the Route Reflector extension:
- Plugins inserted at this point will decode the messages received from neighbours. eBPF bytecode will be inserted here to decode the new BGP attributes (CLUSTER_LIST and ORIGINATOR_ID)
- This insertion point is dedicated to the import filter. The plugin checks if its router-id (or cluster-id) is contained in either CLUSTER_LIST or ORIGINATOR_ID
- Plugins can add new steps in the BGP decision process or modify existing ones.To implement Route Reflectors, the original BGP decision process must be altered
- Handling export filters. The route is only exported according to section 6 of RFC4456
- Serializing the BGP message as it will be transmitted on the wire. The cluster list and the originator ID must be added to the BGP message
Writing an xBGP plugin
xBGP empowers network operators to write their own BGP extensions.
xBGP plugins are functions written in a restricted C language.
Imagine that your BGP implementation contains a flaw that crashes the router if it receives a route with BGP attribute Code 42. One may want to quickly solve the issue to avoid any DoS attack coming through their BGP neighbours. With xBGP, a quick patch can be provided using the following C function attached to the xBGP insertion point #1.
uint64_t parse_attribute(args_t *args) { uint8_t *code; code = get_arg(0); // argument 0 is the code attribute received from the neighbor. if (!code) { // unable to retrieve the argument (internal failure) return EXIT_FAILURE; } // tells the host implementation to reject the route if it contains the BGP attribute with code 42 return code == 42 ? EXIT_FAILURE : 0; }
From this simple example, multiple observations can be made:
- The argument passed to the C function depends on the insertion point the plugin is attached to. In this example, the function retrieves its argument via the special function ‘get_arg’. It tells the virtual machine to copy the data inside a memory space readable by the plugin
- The return value of the function is an indication of the virtual machine to decide the next steps of the protocol. As for arguments, it depends on the insertion point. In this case, a return value of 0 says that the operation succeeds. However, if the plugin fails or the routes must be dropped, the function must return EXIT_FAILURE
The API
The xBGP API plays a key role when developing new extensions. As the plugin is executed independently from the host BGP implementation, it cannot directly access the datastructures maintained by the host. Also, xBGP supports any host implementation. Therefore, the API allows converting the internal structures to a neutral representation that every plugin can manipulate.
READ: BGP in 2020 — BGP Update Churn
The API is more flexible than the traditional CLI or Netconf. The plugin can now access more data structure to build complex filters. For example, retrieving the IGP cost associated with the next hop BGP is not an easy task with the current abstraction of any BGP implementation. Thanks to a simple API call, the user plugin can retrieve this information to make further processing.
Demonstrating the programmability of xBGP
xBGP is the framework that enables any BGP implementation to be more flexible. However, this requires some adaptation to be fully compliant.
We adapted both FRRouting and BIRD, two common routing protocols, to make them xBGP compliant.
In our recent paper presented at HotNets 2020, we prove that xBGP can implement several use cases regarding:
- The use of BGP to improve the datacenter use cases
- The validation of BGP routes in the manner of RPKI
- The use of new information that was not easily accessible from the traditional router Command Line Interface
Next steps
We welcome discussions with network operators about their use cases for BGP extensions.
We also welcome discussions with router vendors who would like to integrate in their implementation.
Our xBGP implementations are open-source and more information can be found here.
Thomas Wirtgen is a PhD student examining the extensibility of routing protocols.
The views expressed by the authors of this blog are their own and do not necessarily reflect the views of APNIC. Please note a Code of Conduct applies to this blog.
I think the description of Adj-RIB-in is erroneous. This is the table before applying filters. The main use of this table is to be able to update filters without clearing the BGP session.
Yes indeed, you are right. There is some confusion between the text and Figure 2.
The route is first installed on the ADJ-RIB-IN and then checked using importation filters, where plugins can be attached to them.
I wonder why there are four rib tables in the Figure 2, there are 3 ribs in Section 3.2. Routing Information Base of RFC 4271. I think local rib connect to FIB instead of RIB in figure 2.
I agree, there are 3 RIBs in the original RFC 4271.
Figure 2 represents the workflow that routes can take in the protocol. The fourth RIB highlights that BGP chooses and advertises a single route per prefix to all its neighbors. The best route is updated each time the route decision process is triggered. This was just to distinguish between all acceptable routes and the one chosen by BGP, and thus have a clear representation of those best routes that will be used by BGP later on. But I agree that putting 4 RIBs on the Figure is confusing with RFC 4271.