Last active
June 14, 2023 22:19
-
-
Save oskar456/7264828 to your computer and use it in GitHub Desktop.
A simple script to set up policy routing on linux. It's stateless and detects everything automatically, so all you have to do is to run it after every network subsystem change. I run it in postup and postdown hooks in Gentoo network configuration file.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
IP="/bin/ip" | |
function prepare_rt_table() { | |
local rttables=/etc/iproute2/rt_tables | |
local iface=$1 | |
[[ "${iface}" = 'lo' ]] && return | |
if ! egrep -q "\s${iface}\s*"\$ $rttables; then | |
idx=$(wc -l <$rttables) | |
echo -e "$(( 300 + ${idx} ))\t${iface}" >> $rttables | |
fi | |
} | |
function get_ipv4_addressses() { | |
local iface=$1 | |
$IP -4 addr show dev ${iface} | sed -rn '/inet / s_^.*inet ([0-9.]*)/.*$_\1_p' | |
} | |
function get_ipv6_addressses() { | |
local iface=$1 | |
$IP -6 addr show dev ${iface} | sed -rn '/inet6 / s_^.*inet6 ([0-9a-f:]*)/.*$_\1_p' | |
} | |
function transfer_routes_ipv4() { | |
local iface=$1 | |
$IP -4 route flush table ${iface} | |
while read line; do | |
[[ -z "$line" ]] && continue | |
$IP -4 route add ${line} table ${iface} | |
done <<-EOF | |
$($IP -4 rou show table main | grep "dev ${iface}" |\ | |
sed -r 's_expires [^ ]*__' | sed -r 's_proto [^ ]*__' ) | |
EOF | |
} | |
function transfer_routes_ipv6() { | |
local iface=$1 | |
$IP -6 route flush table ${iface} | |
while read line; do | |
[[ -z "$line" ]] && continue | |
$IP -6 route add ${line} table ${iface} | |
done <<-EOF | |
$($IP -6 rou show table main | grep "dev ${iface}" |\ | |
sed -r 's_expires [^ ]*__' | sed -r 's_proto [^ ]*__' ) | |
EOF | |
} | |
function get_table_id() { | |
local rttables=/etc/iproute2/rt_tables | |
local table=$1 | |
sed -rn "/^\s*[0-9]*\s*${table}/ s_^\s*([0-9]+)\s.*_\1_p" $rttables | |
} | |
function replace_rules_ipv4 { | |
local iface=$1 | |
local tableid=$(get_table_id $iface) | |
while $IP -4 rule show | egrep -q ^${tableid}; do | |
$IP -4 rule del prio ${tableid} | |
done | |
for ipaddr in $(get_ipv4_addressses ${iface}); do | |
$IP -4 rule add prio ${tableid} from ${ipaddr} table ${iface} | |
done | |
} | |
function replace_rules_ipv6 { | |
local iface=$1 | |
local tableid=$(get_table_id $iface) | |
while $IP -6 rule show | egrep -q ^${tableid}; do | |
$IP -6 rule del prio ${tableid} | |
done | |
for ipaddr in $(get_ipv6_addressses ${iface}); do | |
echo $ipaddr | egrep -q '^fe80:' && continue | |
$IP -6 rule add prio ${tableid} from ${ipaddr} table ${iface} | |
done | |
} | |
for ifpath in /sys/class/net/*; do | |
iface=${ifpath##*/} | |
[[ "${iface}" = 'lo' ]] && continue | |
prepare_rt_table ${iface} | |
transfer_routes_ipv4 ${iface} | |
replace_rules_ipv4 ${iface} | |
transfer_routes_ipv6 ${iface} | |
replace_rules_ipv6 ${iface} | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment