62 lines
2.0 KiB
Bash
62 lines
2.0 KiB
Bash
|
#!/bin/sh
|
||
|
|
||
|
# Creating a VRF on linux (like `ip link add vrf_foobar type vrf table 10`) automatically inserts a
|
||
|
# `l3mdev` rule (both IPv4 and IPv6) with preference 1000 by default.
|
||
|
#
|
||
|
# Sadly this means that the `lookup local` with preference 0 (the table `local` containing your
|
||
|
# addresses in the "default VRF") is queried before that, which breaks routing of packets from a
|
||
|
# VRF to your non-VRF addresses.
|
||
|
#
|
||
|
# So you actually want the `l3mdev` rule before the `lookup local` rule, and this script helps with
|
||
|
# that.
|
||
|
#
|
||
|
# Your VRF routing table usually is contained completely in the table you specified when creating
|
||
|
# the VRF; this script also creates an "pref 2000 l3mdev unreachable" rule to make sure within VRFs
|
||
|
# no routes "outside" the VRF are used. (As an alternative you could add `unreachable default
|
||
|
# metric 4278198272` routes in both IPv4 and IPv6 VRF tables).
|
||
|
#
|
||
|
# This should still leave enough room to add policy-based routing rules if you need them.
|
||
|
#
|
||
|
# Also see `vrf_prepare()` and `vrf_create()` in linux kernel
|
||
|
# source:tools/testing/selftests/net/forwarding/lib.sh
|
||
|
|
||
|
set -e
|
||
|
|
||
|
has_rule() {
|
||
|
if [ -n "$(ip $family rule list "$@")" ]; then
|
||
|
# echo "Have: ip $family rule $*"
|
||
|
return 0
|
||
|
else
|
||
|
# echo "Have not: ip $family rule $*"
|
||
|
return 1
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
rule() {
|
||
|
# echo "Running: ip $family rule $*"
|
||
|
ip $family rule "$@"
|
||
|
}
|
||
|
|
||
|
run() {
|
||
|
# move lookup local to pref 32765 (from 0)
|
||
|
if ! has_rule pref 32765 lookup local; then
|
||
|
rule add pref 32765 lookup local
|
||
|
fi
|
||
|
if has_rule pref 0 lookup local; then
|
||
|
rule del pref 0 lookup local
|
||
|
fi
|
||
|
# make sure that in VRFs after failed lookup in the VRF specific table nothing else is reached
|
||
|
if ! has_rule pref 1000 l3mdev; then
|
||
|
# this should be added by the kernel when a VRF is created; add it here for completeness
|
||
|
rule add pref 1000 l3mdev protocol kernel
|
||
|
fi
|
||
|
if ! has_rule pref 2000 l3mdev; then # can't search for actions; so can't make sure this is actually using "unreachable"
|
||
|
rule add pref 2000 l3mdev unreachable
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
family=-4
|
||
|
run
|
||
|
family=-6
|
||
|
run
|