// An example policy script; see "Policy scripts" in bin/bgp/README.md for // everything a function can read and change. // // A function is given a route and the peer it comes from (or goes to). It // may change the route, and returns whether the route is taken (or // announced). Which function is for which peer is said in the // configuration: import { function: "from_peer" }. // // Constants defined here are for every function below. // Where a route was learned: what the rules for announcing it go by. const LEARNED_FROM = #{ customer: "65000:1000", peer: "65000:2000", provider: "65000:3000", route_server: "65000:2000", }; // A customer's route is preferred to a peer's, and that to a provider's: // the first earns money, the last costs it. const PREFERENCE = #{ customer: 300, peer: 200, route_server: 200, provider: 100 }; const BLACKHOLE = "65535:666"; const NO_EXPORT = "65535:65281"; // Routes on their way in. fn from_peer(route, peer) { // Not ours to act on, from just anyone. if route.has_community(BLACKHOLE) { return false; } // Marks in our own range mean something here: nobody else's word for // them is taken. route.remove_community("65000:*"); if peer.role in LEARNED_FROM { route.add_community(LEARNED_FROM[peer.role]); route.local_pref = PREFERENCE[peer.role]; } // A peer can ask to be a last resort: 65000:80 on a route of its own. if route.has_community(peer.asn % 65536, 80) { route.local_pref = 80; } true } // Routes on their way out. fn to_peer(route, peer) { if route.has_community(NO_EXPORT) { return false; } // Only customers are told what we learned from peers and providers. let from_above = route.has_community("65000:2000") || route.has_community("65000:3000"); if from_above && peer.role != "customer" { return false; } // Our marks are our own business. route.remove_community("65000:*"); // Traffic from this one is wanted by another way: the path looks // longer to it. if peer.name == "backup-transit" { route.prepend(2); } true }