Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gateway: Implement daemon for translating babeld to BGP Metrics #989

Open
spolack opened this issue Oct 2, 2024 · 0 comments
Open

gateway: Implement daemon for translating babeld to BGP Metrics #989

spolack opened this issue Oct 2, 2024 · 0 comments

Comments

@spolack
Copy link
Member

spolack commented Oct 2, 2024

In order to attract traffic from internet on the closest gateway (mesh perspective), thus reducing load on gre tunnels we'll have to translate the mesh metric into a BGP metric. Only AS Path is usable for traffic engineering across multiple upstream autonomous systems.

This is already prepared on the bird side in https://github.com/freifunk-berlin/bbb-configs/blob/main/roles/cfg_openwrt/templates/gateway/bird.conf.j2#L14

Basically we'd just need the script to write the export policy in /dev/shm/announcement*.bird.conf and then trigger a bird reload.

The calculations could be done at a configurable interval.

I've written a very scary PoC to validate the strategy. It's on our gateways under /root/metrix.sh

#!/bin/sh

# for every babel metric of $PREPEND_STEP we increase the as path by $PREPEND_STEP_SIZE
PREPEND_STEP=500
PREPEND_STEP_SIZE=2
MAX_PREPENDS=10

FILE="/dev/shm/announcement_babel_to_prepend.bird.conf"


get_routes_metrics() {
  prefix=$1
  # retrieve metrics where nexthop is not gre 
  result="$(echo "dump" | nc ::1 33123 | grep "installed yes" | grep "::/56"  | grep $prefix | grep -v "gre4-" | cut -d " " -f 13)"

  # put in 5k for every nexthop gre interface
  for i in $(echo "dump" | nc ::1 33123 | grep "installed yes" | grep "::/56"  | grep $prefix | grep "gre4-"); do
    result="$result 5000"
  done
  echo $result
}



echo "" > $FILE

for pfx in $(ip -6 r s | grep /44 | cut -d" " -f 2); do
  pfx_grep=$(echo $pfx | awk -F '::' '{print $1}')
  echo Calcualating average for prefix: $pfx
  metrics="$(get_routes_metrics $pfx_grep)"
  avg=$(echo "$metrics" | awk '{x+=$0}END{print x/NR}');
  
  prepends=$(echo "(($avg - $PREPEND_STEP) / $PREPEND_STEP) * $PREPEND_STEP_SIZE" | bc)
  if [[ $prepends -gt $MAX_PREPENDS ]]; then
    prepends=10
  fi
  echo "Average Metric: $avg - Caluclated AS Path Prepends: $prepends"
  
  if [[ $prepends -eq 0 ]]; then
    continue
  fi

  echo "if net = $pfx then {" >> $FILE
  for i in $(seq 1 $prepends); do 
    echo "        bgp_path.prepend(44194);" >> $FILE
  done
  echo "}" >> $FILE
done
birdc configure

Export policy produced by the PoC:

root@saarbruecker-gw:~# cat /dev/shm/announcement_babel_to_prepend.bird.conf 

if net = 2001:bf7:760::/44 then {
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
}
if net = 2001:bf7:780::/44 then {
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
}
if net = 2001:bf7:790::/44 then {
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
}
if net = 2001:bf7:800::/44 then {
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
}
if net = 2001:bf7:810::/44 then {
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
}
if net = 2001:bf7:820::/44 then {
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
}
if net = 2001:bf7:830::/44 then {
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
}
if net = 2001:bf7:840::/44 then {
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
}
if net = 2001:bf7:850::/44 then {
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
}
if net = 2001:bf7:860::/44 then {
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
        bgp_path.prepend(44194);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant