Commit b5335f43 authored by Jouke Witteveen's avatar Jouke Witteveen
Browse files

Support custom MAC address on new interfaces (FS#64766)

Connection types bond, bridge, dummy, vlan, and macvlan create their own
interface. Previously, only macvlan offered control over the MAC address of
the created interface. Now, this functionality is available to all these
connection types.

Thanks to:
Javier <j.e.vasquez.v@gmail.com>
and
David Hummel <hummeltech@dhummel.net>
parent c0196798
...@@ -2,6 +2,8 @@ Description="Example Bridge connection" ...@@ -2,6 +2,8 @@ Description="Example Bridge connection"
Interface=br0 Interface=br0
Connection=bridge Connection=bridge
BindsToInterfaces=(eth0 eth1 tap0) BindsToInterfaces=(eth0 eth1 tap0)
## Use the MAC address of eth1 (may also be set to a literal MAC address)
#MACAddress=eth1
IP=dhcp IP=dhcp
## Ignore (R)STP and immediately activate the bridge ## Ignore (R)STP and immediately activate the bridge
#SkipForwardingDelay=yes #SkipForwardingDelay=yes
...@@ -6,7 +6,7 @@ BindsToInterfaces=eth0 ...@@ -6,7 +6,7 @@ BindsToInterfaces=eth0
# MACVLAN Mode # MACVLAN Mode
Mode="bridge" Mode="bridge"
# Optional static MAC Address for MACVLAN interface # Optional static MAC Address for MACVLAN interface
MACAddress="" #MACAddress="12:34:56:78:9a:bc"
IP=static IP=static
Address="192.168.0.100/24" Address="192.168.0.100/24"
Gateway="192.168.0.1" Gateway="192.168.0.1"
......
...@@ -83,6 +83,12 @@ GENERAL OPTIONS ...@@ -83,6 +83,12 @@ GENERAL OPTIONS
profile. If this variable is not specified, it defaults to the value profile. If this variable is not specified, it defaults to the value
of 'Interface='. of 'Interface='.
'MACAddress='::
Optional MAC address for newly created interfaces. When set to the
name of an existing interface, the address of that interface is used.
The connection types that create an interface and are able to set a
MAC address are +bond+, +bridge+, +dummy+, +vlan+, and +macvlan+.
'After=()':: 'After=()'::
An array of profile names that should be started before this profile An array of profile names that should be started before this profile
is started. This is only an ordering dependency and is not intended is started. This is only an ordering dependency and is not intended
...@@ -544,9 +550,6 @@ following are understood for connections of the `macvlan' type: ...@@ -544,9 +550,6 @@ following are understood for connections of the `macvlan' type:
Either `bridge', `vepa', `private', or `passthru'. See *ip*(8) for Either `bridge', `vepa', `private', or `passthru'. See *ip*(8) for
details. details.
'MACAddress='::
Optional static MAC address for the `macvlan' type link.
SPECIAL QUOTING RULES SPECIAL QUOTING RULES
--------------------- ---------------------
......
...@@ -11,7 +11,7 @@ bond_up() { ...@@ -11,7 +11,7 @@ bond_up() {
return 1 return 1
fi fi
interface_add bond "$Interface" "" ${Mode:+mode "$Mode"} interface_add bond "$Interface" "$MACAddress" "" ${Mode:+mode "$Mode"}
bring_interface_up "$Interface" bring_interface_up "$Interface"
for slave in "${BindsToInterfaces[@]}"; do for slave in "${BindsToInterfaces[@]}"; do
ip link set dev "$slave" master "$Interface" ip link set dev "$slave" master "$Interface"
......
...@@ -11,8 +11,11 @@ bridge_up() { ...@@ -11,8 +11,11 @@ bridge_up() {
report_error "Interface '$Interface' already exists and is not a bridge" report_error "Interface '$Interface' already exists and is not a bridge"
return 1 return 1
fi fi
if [[ "$MACAddress" ]]; then
report_error "Setting a MAC address on existing bridge interface '$Interface' is unsupported"
fi
else else
interface_add bridge "$Interface" interface_add bridge "$Interface" "$MACAddress"
fi fi
for member in "${BindsToInterfaces[@]}"; do for member in "${BindsToInterfaces[@]}"; do
......
...@@ -11,7 +11,7 @@ dummy_up() { ...@@ -11,7 +11,7 @@ dummy_up() {
return 1 return 1
fi fi
interface_add dummy "$Interface" interface_add dummy "$Interface" "$MACAddress"
bring_interface_up "$Interface" bring_interface_up "$Interface"
ip_set ip_set
} }
......
...@@ -15,10 +15,7 @@ macvlan_up() { ...@@ -15,10 +15,7 @@ macvlan_up() {
return 1 return 1
else else
bring_interface_up "$BindsToInterfaces" bring_interface_up "$BindsToInterfaces"
interface_add macvlan "$Interface" "$BindsToInterfaces" mode "$Mode" interface_add macvlan "$Interface" "$MACAddress" "$BindsToInterfaces" mode "$Mode" || return 1
if [[ $MACAddress ]]; then
ip link set dev "$Interface" address "$MACAddress" || return 1
fi
fi fi
ethernet_up ethernet_up
} }
......
...@@ -15,7 +15,7 @@ vlan_up() { ...@@ -15,7 +15,7 @@ vlan_up() {
return 1 return 1
else else
bring_interface_up "$BindsToInterfaces" bring_interface_up "$BindsToInterfaces"
interface_add vlan "$Interface" "$BindsToInterfaces" id "$VLANID" interface_add vlan "$Interface" "$MACAddress" "$BindsToInterfaces" id "$VLANID"
fi fi
ethernet_up ethernet_up
......
...@@ -20,11 +20,15 @@ is_interface() { ...@@ -20,11 +20,15 @@ is_interface() {
## Add an interface ## Add an interface
# $1: interface type # $1: interface type
# $2: interface name # $2: interface name
# $3: interface link (optional) # $3: interface MAC address (optional)
# $4...: additional arguments # $4: interface link (optional)
# $5...: additional type related arguments
interface_add() { interface_add() {
local type="$1" name="$2" link="$3" local type="$1" name="$2" address="$3" link="$4"
do_debug ip link add ${link:+link "$link"} name "$name" type "$type" "${@:4}" $LinkOptions || return if [[ -e "/sys/class/net/$address/address" ]]; then
address=$(< "/sys/class/net/$address/address")
fi
do_debug ip link add ${link:+link "$link"} name "$name" ${address:+address "$address"} type "$type" "${@:5}" $LinkOptions || return
load_interface_config "$name" load_interface_config "$name"
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment