Merging multiple routes into a single multipath route
Daniel Gröber
dxld at darkboxed.org
Sun May 8 10:26:26 CEST 2022
Hi Johannes,
On Tue, May 03, 2022 at 04:07:08PM +0200, Johannes Erwerle wrote:
> I would like to use both uplinks via the linux multipath routing and I am
> searching for a way to "merge" both default routes that I get into one route
> with multiple next hops.
>
> Is there a way to accomplish that with bird? (or any other tool?)
Instead of letting the dhcp client install the routes and then trying to
massage them into shape you could do this directly by configuring the dhcp
client appropriately. The isc-dhcp client actually and very good support
for scripting in dhclient-*-hooks.d that lets you override what the
dhclient-script (which handles the OS specific stuff) does by default.
I have been working on a dhcp script myself to allow for VRRP redundancy on
a DHCP managed interface. You should be able to use the
neutralize_ip_change hack I use to override iproute2 commands called by
dhclient-script for your purposes too:
neutralize_ip_change () {
ip () neutered_ip "$@"
}
neutered_ip () { : do stuff and call real "ip" command; }
This works because dhclient-script (a bash script) sources the hooks so we
can mess with the shell environment to override the "ip" command with a
shell function that matches on the args and does whatever we want.
Script attached since I haven't published it anywhere yet. Note this is
only lightly tested so far but I'd be happy to help you make this work for
your use-case.
--Daniel
-------------- next part --------------
#!/bin/sh
# Install into /etc/dhcp and symlink to /etc/dhcp/dhclient-{enter,exit}-hooks.d
IFACE=enp9s0f1.4
VRID=4
PRIO=100
DUMMYIP_OLD=192.168.254.254
DUMMYIP_NEW=192.168.254.253
PIDFILE=/var/run/"vrrpd_${IFACE}_${VRID}.pid"
HOOKDIR="$(basename "$dir")"
## Debugging
#set -x
#exec >> /tmp/dhcp.log 2>&1
echo $HOOKDIR $reason $interface >>/tmp/dhcp.log
set | grep 'ip_address\|route' | sort >>/tmp/dhcp.log
printf '\n\n' >>/tmp/dhcp.log
killvrrp () {
echo "killvrrp $PIDFILE" >>/tmp/dhcp.log
[ -n $old_ip_address ] || return
if [ -e "$PIDFILE" ]; then
kill "$(cat $PIDFILE)" || true
fi
}
startvrrp () {
echo "startvrrp $new_ip_address\n" >>/tmp/dhcp.log
[ -n $new_ip_address ] || return
echo vrrpd -D -n -i "$interface" -v "$VRID" -p "$PRIO" "$new_ip_address"
vrrpd -D -n -i "$interface" -v "$VRID" -p "$PRIO" "$new_ip_address" ||
exit_status=1
}
# dhclient-script insists on fucking with the IP address, we don't want any
# of that since vrrpd will do it.
neutralize_ip_change () {
ip () neutered_ip "$@"
}
neutered_ip () {
[ $# -ge 3 ] || { ip "$@"; return; }
if
[ "$1" = "-4" -a "$2" = addr -a "$3" = flush ] ||
[ "$1" = "-4" -a "$2" = addr -a "$3" = add ] ||
[ "$1" = "-4" -a "$2" = addr -a "$3" = change ]
then
echo ignored "$@"
return
else
echo =ip "$@"
command ip "$@"
fi
}
do_vrrp () {
if [ "$HOOKDIR" = "dhclient-enter-hooks.d" ]; then
case $reason in
BOUND | REBOOT | TIMEOUT) ;; # Just started shouldn't be running
RENEW | REBIND)
[ $new_ip_address = $old_ip_address] || killvrrp ;;
EXPIRE | FAIL | RELEASE | STOP | TIMEOUT)
killvrrp ;;
esac
neutralize_ip_change
elif [ "$HOOKDIR" = "dhclient-exit-hooks.d" ]; then
case $reason in
# Note: TIMEOUT is when we can't reach a dhcp server during
# startup but have a valid lease still that we're going to
# use.
BOUND | REBOOT | TIMEOUT)
startvrrp ;;
RENEW | REBIND)
[ $new_ip_address = $old_ip_address] || startvrrp ;;
EXPIRE | FAIL | RELEASE) ;;
esac
fi
}
if [ "$interface" = $IFACE ]; then
do_vrrp
fi
More information about the Bird-users
mailing list