mirror of
https://github.com/kernelkit/infix.git
synced 2026-08-01 21:33:02 +02:00
224 lines
5.5 KiB
Bash
Executable File
224 lines
5.5 KiB
Bash
Executable File
#!/bin/sh
|
|
# Generates ietf-intefaces + ietf-ip settings for all detected interfaces.
|
|
#
|
|
# Interfaces must be of type Ethernet (copper/sfp), not be "internal"
|
|
# DSA ports, and must have a "parentbus", i.e., be physical ports.
|
|
#
|
|
# The script mainly caters to two modes of operation: switch and router.
|
|
# There is also a mixed mode with limited usability. Other use-cases or
|
|
# combinations we recommend overriding this script in your br2-external
|
|
# rootfs overlay.
|
|
#
|
|
### Router Mode (default) ##############################################
|
|
# By default this script generates plain interfaces with IPv6 autoconfig
|
|
# (EUI64) enabled. Useful both in a plain router and a Fail Secure mode
|
|
# where any switchcore-backed ports should be prevented from switching.
|
|
#
|
|
# The default mode currently does not support the '-4' or '-d' options
|
|
# for IPv4 ZeroConf or DHCPv4 address, beacause they require source
|
|
# routing, or similar, to work. IPv6 does not require that and is
|
|
# therefore the recommended access method. A separate (and optional)
|
|
# 'gen-cfg-custom' script is checked for in the bootstrap script which
|
|
# can be used to enable IPv4 and DHCP on a single service interface if
|
|
# needed.
|
|
#
|
|
### Bridge Mode ########################################################
|
|
# The '-b brname' option triggers the bridge mode, creating a 'brname'
|
|
# bridge interface using all interfaces classified in 'group port' by
|
|
# the nameif script. In the bridge mode port interfaces do not have any
|
|
# IP address, the IPv6 autoconfig address is instead set on 'brN'. If
|
|
# the '-4' option is set, ZeroConfig (169.254.x.y) is anabled on 'brN'.
|
|
# If the '-d' option is set, a DHCPv4 client is enabled on 'brN'.
|
|
#
|
|
### Mixed Mode #########################################################
|
|
# A "mixed mode" is also supported, where the system may have multiple
|
|
# ports in a switchcore, but some Ethernet interfaces directly connected
|
|
# to the SoC. In this case, if '-b brname' is given, all 'group port'
|
|
# interfaces will be placed in the bridge 'brname' and all other
|
|
# interfaces will be brought up and given an IPv6 address (like above).
|
|
#
|
|
set -e
|
|
|
|
bridge=
|
|
ipv4=false
|
|
dhcp=
|
|
|
|
usage()
|
|
{
|
|
cat <<EOF
|
|
Usage: gen-interfaces [-4d] [-b brN]
|
|
|
|
-4 Enable IPv4 ZeroConf, only for brN in bridge mode
|
|
-b brN Bridged mode, add all port interfaces to brN
|
|
-d Enable DHCPv4 client, only for brN in bridge mode
|
|
|
|
EOF
|
|
exit 0
|
|
}
|
|
|
|
iftype()
|
|
{
|
|
iftype=$(ip -d -j link show "$1" |jq -r .[].parentbus)
|
|
if [ "$iftype" = "virtio" ]; then
|
|
echo "infix-if-type:etherlike"
|
|
else
|
|
echo "infix-if-type:ethernet"
|
|
fi
|
|
}
|
|
|
|
# shellcheck disable=SC3043
|
|
gen_iface_json()
|
|
{
|
|
local ifname="$1"
|
|
local br="$2"
|
|
|
|
cat <<EOF
|
|
,{
|
|
"name": "$ifname",
|
|
"type": "$(iftype "$ifname")",
|
|
EOF
|
|
|
|
if [ -n "$br" ]; then
|
|
cat <<EOF
|
|
"ietf-ip:ipv6": {
|
|
"enabled": false
|
|
},
|
|
"infix-interfaces:bridge-port": {
|
|
"bridge": "$br"
|
|
}
|
|
EOF
|
|
else
|
|
cat <<EOF
|
|
"ietf-ip:ipv6": {}
|
|
EOF
|
|
fi
|
|
|
|
cat <<EOF
|
|
}
|
|
EOF
|
|
}
|
|
|
|
filter_iface_ports()
|
|
{
|
|
ifaces="$1"
|
|
ports="$2"
|
|
|
|
iface_devs=""
|
|
for phy in $ifaces; do
|
|
found=""
|
|
for port in $ports; do
|
|
if [ "$port" = "$phy" ]; then
|
|
found=true
|
|
break
|
|
fi
|
|
done
|
|
if [ -z "$found" ]; then
|
|
iface_devs="$iface_devs $phy"
|
|
fi
|
|
done
|
|
echo -n "$iface_devs"
|
|
}
|
|
|
|
while [ "$1" != "" ]; do
|
|
case $1 in
|
|
-4)
|
|
ipv4=true
|
|
;;
|
|
-b)
|
|
bridge="$2"
|
|
shift
|
|
;;
|
|
-d)
|
|
dhcp=true
|
|
;;
|
|
-h)
|
|
usage
|
|
;;
|
|
*)
|
|
break
|
|
esac
|
|
shift
|
|
done
|
|
|
|
# All exeternal interfaces
|
|
phys_ifaces=$(ip -d -j link show | jq -r '
|
|
.[] |
|
|
select(.link_type == "ether") |
|
|
select(.group != "internal") |
|
|
select(has("parentbus")) |
|
|
.ifname' | sort -V)
|
|
# All interfaces classified as switch ports
|
|
ports=$(ip -d -j link show group port | jq -r '
|
|
.[] |
|
|
select(.link_type == "ether") |
|
|
select(.group != "internal") |
|
|
select(has("parentbus")) |
|
|
.ifname' | sort -V)
|
|
|
|
# Remaining external interfaces not classified as switch ports
|
|
ifaces="$(filter_iface_ports "$phys_ifaces" "$ports")"
|
|
|
|
cat <<EOF
|
|
{
|
|
"ietf-interfaces:interfaces": {
|
|
"interface": [
|
|
{
|
|
"name": "lo",
|
|
"type": "infix-if-type:loopback",
|
|
"ietf-ip:ipv4": {
|
|
"address": [{ "ip": "127.0.0.1", "prefix-length": 8 }]
|
|
},
|
|
"ietf-ip:ipv6": {
|
|
"address": [{ "ip": "::1", "prefix-length": 128 }]
|
|
}
|
|
EOF
|
|
if [ -n "$bridge" ]; then
|
|
cat <<EOF
|
|
},
|
|
{
|
|
"name": "$bridge",
|
|
"type": "infix-if-type:bridge",
|
|
"ietf-ip:ipv4": {
|
|
"infix-ip:autoconf": {
|
|
"enabled": $ipv4
|
|
}
|
|
},
|
|
"ietf-ip:ipv6": {
|
|
"enabled": true,
|
|
"autoconf": {
|
|
"create-global-addresses": true
|
|
}
|
|
},
|
|
"infix-interfaces:bridge": {
|
|
"multicast": {
|
|
"snooping": true,
|
|
"querier": "auto",
|
|
"query-interval": 125
|
|
}
|
|
}
|
|
EOF
|
|
fi
|
|
|
|
cat <<EOF
|
|
}
|
|
$(for iface in $ifaces; do gen_iface_json "$iface"; done)
|
|
$(for iface in $ports; do gen_iface_json "$iface" "$bridge"; done)
|
|
]
|
|
EOF
|
|
if [ "$dhcp" = "true" ] && [ -n "$bridge" ]; then
|
|
cat <<EOF
|
|
},
|
|
"infix-dhcp-client:dhcp-client": {
|
|
"enabled": true,
|
|
"client-if": [
|
|
{
|
|
"if-name": "$bridge"
|
|
}
|
|
]
|
|
EOF
|
|
fi
|
|
cat <<EOF
|
|
}
|
|
}
|
|
EOF
|