UNPKG

2.51 kBPlain TextView Raw
1import { Route } from '../types/routing'
2import { create as createLogger } from '../common/log'
3const log = createLogger('dragon')
4import { Relation, getRelationPriority } from './relation'
5import ForwardingRoutingTable from '../services/forwarding-routing-table'
6
7/**
8 * Check whether a route can be filtered out based on DRAGON rules.
9 *
10 * See http://route-aggregation.net/.
11 *
12 * The basic idea is that if we have a more general route that is as good as a
13 * more specific route, we don't need to advertise the more specific route.
14 *
15 * This removes a lot of routing updates across a large network and has basically
16 * no downside.
17 *
18 * Note that we use DRAGON filtering, but *not* DRAGON aggregation. There are
19 * several reasons for this:
20 *
21 * * ILP address space is a lot less dense than IPv4 address space, so
22 * DRAGON aggregation would not be a significant optimization.
23 *
24 * * We may want to secure our routing protocol using a mechanism similar to
25 * BGPsec, which precludes aggregation.
26 *
27 * * We will recommend that owners of tier-1 ILP address space are also real
28 * connectors which participate in the routing protocol and originate a route
29 * advertisement for their tier-1 prefix. This will enable DRAGON filtering
30 * to apply to a lot more situations where otherwise only DRAGON aggregation
31 * would be applicable.
32 */
33export function canDragonFilter (
34 routingTable: ForwardingRoutingTable,
35 getRelation: (prefix: string) => Relation,
36 prefix: string,
37 route: Route
38): boolean {
39 // Find any less specific route
40 for (const parentPrefix of routingTable.getKeysPrefixesOf(prefix)) {
41 const parentRouteUpdate = routingTable.get(parentPrefix)
42
43 if (!parentRouteUpdate || !parentRouteUpdate.route) {
44 log.warn('found a parent prefix, but no parent route; this should never happen. prefix=%s parentPrefix=%s', prefix, parentPrefix)
45 continue
46 }
47
48 const parentRoute = parentRouteUpdate.route
49
50 if (parentRoute.nextHop === '') {
51 // We are the origin of the parent route, cannot DRAGON filter
52 continue
53 }
54
55 const parentRelation = getRelation(parentRoute.nextHop)
56 const childRelation = getRelation(route.nextHop)
57 if (getRelationPriority(parentRelation) < getRelationPriority(childRelation)) {
58 // The more specific route is better for us, so we keep it
59 continue
60 }
61
62 log.trace('applied DRAGON route filter. prefix=%s parentPrefix=%s', prefix, parentPrefix)
63 return true
64 }
65
66 return false
67}