---
layout: page
title: How are BGP routes selected and how can this be influenced?
permalink: /blog/bgp-route-selection-en/
keywords: bgp,bgp route selection,bird route selection,path prepending,multiple exit discriminator,med,routing route selection,bird,networking,network,dn42
description: How are routes selected in BGP? How can you influence this selection? Here I explain the criteria as well as possibilities for manipulation like Path Prepending, BGP local preference and Multiple Exit Discriminator (MED).
lang: en
date: 2023-03-05 00:00:00 +0100
feed: true
---

## How are BGP routes selected?

The following are criteria in bird:

1. The route with the **highest** weight is preferred. For this there is the value `preference` in bird. This is used for example to prefer IGP over EGP - for example Babel over BGP.
2. The route with the **highest** local preference is selected. This can be influenced in the import filter with the variable `bgp_local_pref`. The default preference is 100.
3. The route with the **shortest** AS path is preferred. This is a decisive criterion in all implementations. The path basically specifies (exception: Path Prepending) how many autonomous systems must be traversed to reach the destination.
4. Next, a very rarely used value is checked: the origin. Routes received via IGP are preferred. However, in bird `preference` is now used.
5. If one has multiple peerings with the same autonomous system, the **smallest** multiple exit discriminator (MED) is preferred. For example, if one is connected once a dedicated line and once via an IXP, one generally wants to prefer the dedicated line since it does not have to be shared. Therefore routes, which were received over it, get a smaller MED.
6. Routes received over eBGP are preferred over routes received over iBGP. This means, bird tends to use the routes to an external autonomous system instead of forwarding them further into its own autonomous system.
7. Routes with the **least** internal distance to a boundary router are preferred. Thus, routes coming from routers that are externally connected to other autonomous systems are preferred.
8. The route from the router with the **lowest** router ID is preferred.

However, one should note that the criteria are implementation specific. For example, the criteria and order are a little bit different for FRR.

## How to influence the route selection?

### Path Prepending

Path prepending is a popular tactic to make a path less attractive. As you can see from the criteria above, AS path length is used as a criterion quite high up. The longer the AS path, the less attractive the route. Now, if you don't want a route to be used preferentially, you can make the AS path longer and thus make the route less attractive.
In practice, you append your own AS number to the path. However, this also means that Path Prepending is recognizable, which is not a problem in well-configured systems. To perform path prepending in bird, there is the function `prepend`:
```bird
bgp_path.prepend(64500);
```
In this code section, for example, we would prepend the AS number `64500` to the path. Here, the argument *does not* specify the number of prepends, but the AS number to be prepended. In other BGP implementations, however, the argument can also specify the number!
In practice one uses one to three prepends. After that, the route becomes so unattractive that it is almost never used.
Path prepending is therefore - if used correctly - a strong means to make a route globally less attractive. Path prepending goes beyond one's own and neighboring autonomous systems.

### BGP local preference

Local preference is a very powerful tool - and could almost be called brute force. The AS path length or other criteria are no longer checked if a single route to the destination has a high preference. Local preference should therefore be used carefully.
A good use of it would be to ensure that routes from a neighboring AS are sent directly to it.
```bird
if (bgp_path.len = 1) then
    bgp_local_pref = bgp_local_pref + 700;
```
If the AS path length is one, it means that one have a direct route to the destination AS. So with this code block in the import filter one can force that this direct route is used then.

#### Why not `bgp_path.first = bgp_path.last`?

This is one of the reasons why local preference can be so dangerous. If someone intentionally makes they AS path longer (path prepending), this someone intentionally wants to achieve that you choose another route. With this command you would make the effort ineffective.
For example, one could be peered a two points with an AS. Now one connection is temporarily unstable and the other continues to be stable. During the time when one connection is unstable, the other connection should be preferred - but the unstable connection should not be cut. Therefore, Path Prepending makes the unstable connection less attractive. However, since the local preference is checked before the AS path length, Path Prepending is ignored and the unstable connection is preferred.

#### One cannot see infinitely far

Another reason to avoid local preferences is that you can only evaluate the connection between yourself and the neighboring AS - for example, how stable the connection is or what the latency is.
Example: there are three autonomous systems, all three are interconnected to each other. The connection between AS A and AS B is very good. The connection between AS A and AS C is okay. However, the connection between AS B and AS C is very poor. AS A now wants to reach AS C. The reasonable route would be to use the direct route from AS A to AS C. The the connection there would be okay. However, AS A has set up a high local preference for all routes from AS B because the connection between these ASes is very good. So according to the route selection algorithm, the route via AS B is used - AS A -> AS B -> AS C. However, since the connection between AS B and AS C is very bad, now the connection between AS A and AS C is also very bad - it would have been better if AS A had established a direct connection to AS C, as it would have been without local preference.
This example shows that one can always only estimate the connection to the neighboring ASes and not their connection to other systems.

![The situation described above with AS A, AS B and AS C shown as a diagram.](../../assets/img/bgp-route-selection/bgp-local-pref-is-evil.png)

#### Communities

In BGP, there are communities. For example, in dn42, BGP communities are used to communicate bandwidth, latency, and encryption. However, the implementation of these communities is optional. Furthermore, the communities can and should be adjusted by any AS on the path - for example, the highest bandwidth from a route is always that from the node on the path with the lowest bandwidth. This raises two problems: ASes may not implement the communities and therefore important information may be lost. Furthermore, the communities may be processed incorrectly due to misconfiguration.
In addition, basing local preference on the communities would be a bad security practice. Then, a malicious actor could use the communities to "claim" to have a very good connection to all systems. This would result in the local preference ensuring that every route, and thus traffic, goes through the attacker.

## Multiple Exit Discriminator (MED)

It may happen that two autonomous systems peer over two or more connections. Without MED, the route is selected by the router with the lowest router ID. This is not a useful selection criterion, but it is deterministic (the same result always occurs for the same conditions). Now you can assign a MED to each route. In this case, the **smallest** MED is preferred.
Example: Two autonomous systems AS A and AS B are peered together by two connections. One connection is stable and the other is unstable. However, one would like to keep the unstable connection as a backup since it would not be better alternate route. If you want to prefer the stable connection, you can set a lower MED there. This is done in bird by setting `bgp_med` to the appropriate value.

![The situation described above with AS A and AS B shown as a diagram.](../../assets/img/bgp-route-selection/bgp-med-is-good.png)

## Router ID

As a final comparison criterion, the router ID is used by many BGP implementations, including bird. The router ID is normally represented as IPv4 and is used to uniquely identify a router among its neighbors. This decision criterion is deterministic, but not very useful. In bird, one can modify this last decision criterion to select the route based on the **oldest** route rather than the router ID.
To use this alternative decision criterion, use the statement `prefer older on;` when setting up your BGP session. The statement is written to `protocol bgp` and then applies to the entire BGP session.


# Links

- [FRR BGP Route Selection](http://docs.frrouting.org/en/latest/bgp.html#route-selection)
- [Bird BGP](https://bird.network.cz/?get_doc&v=20&f=bird-6.html#ss6.3)
- [Bird Route Selection](https://bird.network.cz/?get_doc&v=20&f=bird-2.html#ss2.1)
- [BGP communities in dn42](https://dn42.dev/howto/Bird-communities)
