PBR with netifd

  • This instruction configures PBR with netifd on OpenWrt.
  • Follow the automated section for quick setup.
  • Utilize multiple upstream interfaces with their own gateways.
  • Route different subnets/clients to a different gateway.
  • Prioritize routing for local subnets and tunnel endpoints.

Automatically set up PBR with netifd:

  • Provide the PBR protocol for netifd.
  • Set up named routing tables for each interface.
  • Assign each interface to its own routing table.
  • Use the PBR protocol for unmanaged interfaces.
  • Add default routing rules after subnets/endpoints.

Add custom routing rules before the default ones.

Sub-command Description
setup Set up policy-based routing.
unset Unset policy-based routing.
# Configure profile
mkdir -p /etc/profile.d
cat << "EOF" > /etc/profile.d/pbr.sh
pbr() {
local PBR_CMD="${1}"
case "${PBR_CMD}" in
(setup|unset)
. /lib/functions.sh
. /lib/functions/network.sh
config_load network
config_foreach pbr_iface_"${PBR_CMD}" interface
pbr_rules_"${PBR_CMD}"
pbr_proto_"${PBR_CMD}"
uci commit network
/etc/init.d/network reload ;;
(*) command pbr "${@}" ;;
esac
}
 
pbr_iface_setup() {
local NET_CONF="${1}"
local NET_PROTO
local NET_RT
local NET_RT6
config_get NET_PROTO "${NET_CONF}" proto
config_get NET_RT "${NET_CONF}" ip4table "${NET_CONF}"
config_get NET_RT6 "${NET_CONF}" ip6table "${NET_CONF}"
case "${NET_CONF}" in
(loopback) return 0 ;;
esac
case "${NET_PROTO}" in
(gre*|vti*|vxlan|xfrm|relay) return 0 ;;
(none) NET_PROTO="pbr" ;;
(dhcp) NET_RT6= ;;
(dhcpv6) NET_RT=
NET_RT6="${NET_RT6%6}" ;;
esac
uci -q batch << EOI
set network.'${NET_CONF}'.proto='${NET_PROTO}'
set network.'${NET_CONF}'.ip4table='${NET_RT}'
set network.'${NET_CONF}'.ip6table='${NET_RT6}'
EOI
pbr_table_"${PBR_CMD}"
}
 
pbr_iface_unset() {
local NET_CONF="${1}"
local NET_PROTO
config_get NET_PROTO "${NET_CONF}" proto
case "${NET_CONF}" in
(loopback) return 0 ;;
esac
case "${NET_PROTO}" in
(gre*|vti*|vxlan|xfrm|relay) return 0 ;;
(pbr) NET_PROTO="none" ;;
esac
uci -q batch << EOI
set network.'${NET_CONF}'.proto='${NET_PROTO}'
delete network.'${NET_CONF}'.ip4table
delete network.'${NET_CONF}'.ip6table
EOI
pbr_table_"${PBR_CMD}"
}
 
pbr_table_setup() {
local NET_RTID="$(sort -r -n /etc/iproute2/rt_tables \
| grep -o -E -m 1 "^[0-9]+")"
NET_RT="${NET_RT:-${NET_RT6}}"
if ! grep -q -E -e "^[0-9]+\s+${NET_RT}$" \
/etc/iproute2/rt_tables
then sed -i -e "\$a $((NET_RTID+1))\t${NET_RT}" \
/etc/iproute2/rt_tables
fi
}
 
pbr_table_unset() {
sed -i -n -r -e "/^(#|(128|25[3-5])\s).*$/p" \
/etc/iproute2/rt_tables
}
 
pbr_rules_setup() {
local NET_CONF
local NET_RT
local NET_RT6
network_flush_cache
config_load network
network_find_wan NET_CONF
config_get NET_RT "${NET_CONF}" ip4table
network_find_wan6 NET_CONF
config_get NET_RT6 "${NET_CONF}" ip6table
uci -q batch << EOI
set network.default='rule'
set network.default.lookup='${NET_RT}'
set network.default.priority='80000'
set network.default6='rule6'
set network.default6.lookup='${NET_RT6}'
set network.default6.priority='80000'
EOI
}
 
pbr_rules_unset() {
uci -q batch << EOI
delete network.default
delete network.default6
EOI
}
 
pbr_proto_setup() {
cat << "EOI" > /lib/netifd/proto/pbr.sh
#!/bin/sh
 
proto_pbr_setup() {
local NET_CONF="${1}"
local NET_DEV
local NET_RT
local NET_RT6
config_load network
config_get NET_DEV "${NET_CONF}" device
config_get NET_RT "${NET_CONF}" ip4table
config_get NET_RT6 "${NET_CONF}" ip6table
if [ -n "${NET_RT}" ]
then ip route add default \
dev "${NET_DEV}" table "${NET_RT}"
fi
if [ -n "${NET_RT6}" ]
then ip -6 route add default \
dev "${NET_DEV}" table "${NET_RT6}"
fi
proto_init_update "${NET_DEV}" 1
proto_send_update "${NET_CONF}"
}
 
proto_pbr_teardown() {
local NET_CONF="${1}"
}
 
if [ -z "${INCLUDE_ONLY}" ]
then
. /lib/functions.sh
. /lib/functions/network.sh
. ../netifd-proto.sh
init_proto "${@}"
add_protocol pbr
fi
EOI
chmod +x /lib/netifd/proto/pbr.sh
cat << "EOI" >> /etc/sysupgrade.conf
/lib/netifd/proto/pbr.sh
EOI
}
 
pbr_proto_unset() {
rm -f /lib/netifd/proto/pbr.sh
}
EOF
. /etc/profile.d/pbr.sh
# Set up PBR
pbr setup
uclient-fetch -O pbr.sh "https://openwrt.org/_export/code/docs/guide-user/network/routing/pbr_netifd?codeblock=0"
. ./pbr.sh
This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website.More information about cookies
  • Last modified: 2021/11/01 07:21
  • by vgaetera