network: Add support for multiple addresses and HW addresses
Logical Interfaces can be assigned a hardware address allowing them to match on MAC address. The static config method also needs to support specifying multiple addresses.
This commit is contained in:
parent
604ef7ecb4
commit
4a2e417781
@ -2,6 +2,7 @@ package network
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -25,13 +26,21 @@ type networkInterface interface {
|
|||||||
|
|
||||||
type logicalInterface struct {
|
type logicalInterface struct {
|
||||||
name string
|
name string
|
||||||
|
hwaddr net.HardwareAddr
|
||||||
config configMethod
|
config configMethod
|
||||||
children []networkInterface
|
children []networkInterface
|
||||||
configDepth int
|
configDepth int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *logicalInterface) Network() string {
|
func (i *logicalInterface) Network() string {
|
||||||
config := fmt.Sprintf("[Match]\nName=%s\n\n[Network]\n", i.name)
|
config := fmt.Sprintln("[Match]")
|
||||||
|
if i.name != "" {
|
||||||
|
config += fmt.Sprintf("Name=%s\n", i.name)
|
||||||
|
}
|
||||||
|
if i.hwaddr != nil {
|
||||||
|
config += fmt.Sprintf("MACAddress=%s\n", i.hwaddr)
|
||||||
|
}
|
||||||
|
config += "\n[Network]\n"
|
||||||
|
|
||||||
for _, child := range i.children {
|
for _, child := range i.children {
|
||||||
switch iface := child.(type) {
|
switch iface := child.(type) {
|
||||||
@ -47,8 +56,8 @@ func (i *logicalInterface) Network() string {
|
|||||||
for _, nameserver := range conf.nameservers {
|
for _, nameserver := range conf.nameservers {
|
||||||
config += fmt.Sprintf("DNS=%s\n", nameserver)
|
config += fmt.Sprintf("DNS=%s\n", nameserver)
|
||||||
}
|
}
|
||||||
if conf.address.IP != nil {
|
for _, addr := range conf.addresses {
|
||||||
config += fmt.Sprintf("\n[Address]\nAddress=%s\n", conf.address.String())
|
config += fmt.Sprintf("\n[Address]\nAddress=%s\n", addr.String())
|
||||||
}
|
}
|
||||||
for _, route := range conf.routes {
|
for _, route := range conf.routes {
|
||||||
config += fmt.Sprintf("\n[Route]\nDestination=%s\nGateway=%s\n", route.destination.String(), route.gateway)
|
config += fmt.Sprintf("\n[Route]\nDestination=%s\nGateway=%s\n", route.destination.String(), route.gateway)
|
||||||
|
@ -181,9 +181,11 @@ func TestVLANInterfaceNetwork(t *testing.T) {
|
|||||||
logicalInterface{
|
logicalInterface{
|
||||||
name: "testname",
|
name: "testname",
|
||||||
config: configMethodStatic{
|
config: configMethodStatic{
|
||||||
address: net.IPNet{
|
addresses: []net.IPNet{
|
||||||
IP: []byte{192, 168, 1, 100},
|
{
|
||||||
Mask: []byte{255, 255, 255, 0},
|
IP: []byte{192, 168, 1, 100},
|
||||||
|
Mask: []byte{255, 255, 255, 0},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
nameservers: []net.IP{
|
nameservers: []net.IP{
|
||||||
[]byte{8, 8, 8, 8},
|
[]byte{8, 8, 8, 8},
|
||||||
|
@ -37,7 +37,7 @@ type route struct {
|
|||||||
type configMethod interface{}
|
type configMethod interface{}
|
||||||
|
|
||||||
type configMethodStatic struct {
|
type configMethodStatic struct {
|
||||||
address net.IPNet
|
addresses []net.IPNet
|
||||||
nameservers []net.IP
|
nameservers []net.IP
|
||||||
routes []route
|
routes []route
|
||||||
hwaddress net.HardwareAddr
|
hwaddress net.HardwareAddr
|
||||||
@ -193,20 +193,21 @@ func parseInterfaceStanza(attributes []string, options []string) (*stanzaInterfa
|
|||||||
switch confMethod {
|
switch confMethod {
|
||||||
case "static":
|
case "static":
|
||||||
config := configMethodStatic{
|
config := configMethodStatic{
|
||||||
|
addresses: make([]net.IPNet, 1),
|
||||||
routes: make([]route, 0),
|
routes: make([]route, 0),
|
||||||
nameservers: make([]net.IP, 0),
|
nameservers: make([]net.IP, 0),
|
||||||
}
|
}
|
||||||
if addresses, ok := optionMap["address"]; ok {
|
if addresses, ok := optionMap["address"]; ok {
|
||||||
if len(addresses) == 1 {
|
if len(addresses) == 1 {
|
||||||
config.address.IP = net.ParseIP(addresses[0])
|
config.addresses[0].IP = net.ParseIP(addresses[0])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if netmasks, ok := optionMap["netmask"]; ok {
|
if netmasks, ok := optionMap["netmask"]; ok {
|
||||||
if len(netmasks) == 1 {
|
if len(netmasks) == 1 {
|
||||||
config.address.Mask = net.IPMask(net.ParseIP(netmasks[0]).To4())
|
config.addresses[0].Mask = net.IPMask(net.ParseIP(netmasks[0]).To4())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if config.address.IP == nil || config.address.Mask == nil {
|
if config.addresses[0].IP == nil || config.addresses[0].Mask == nil {
|
||||||
return nil, fmt.Errorf("malformed static network config for %q", iface)
|
return nil, fmt.Errorf("malformed static network config for %q", iface)
|
||||||
}
|
}
|
||||||
if gateways, ok := optionMap["gateway"]; ok {
|
if gateways, ok := optionMap["gateway"]; ok {
|
||||||
|
@ -194,9 +194,11 @@ func TestParseVLANStanzas(t *testing.T) {
|
|||||||
|
|
||||||
func TestParseInterfaceStanzaStaticAddress(t *testing.T) {
|
func TestParseInterfaceStanzaStaticAddress(t *testing.T) {
|
||||||
options := []string{"address 192.168.1.100", "netmask 255.255.255.0"}
|
options := []string{"address 192.168.1.100", "netmask 255.255.255.0"}
|
||||||
expect := net.IPNet{
|
expect := []net.IPNet{
|
||||||
IP: net.IPv4(192, 168, 1, 100),
|
{
|
||||||
Mask: net.IPv4Mask(255, 255, 255, 0),
|
IP: net.IPv4(192, 168, 1, 100),
|
||||||
|
Mask: net.IPv4Mask(255, 255, 255, 0),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
iface, err := parseInterfaceStanza([]string{"eth", "inet", "static"}, options)
|
iface, err := parseInterfaceStanza([]string{"eth", "inet", "static"}, options)
|
||||||
@ -207,7 +209,7 @@ func TestParseInterfaceStanzaStaticAddress(t *testing.T) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(static.address, expect) {
|
if !reflect.DeepEqual(static.addresses, expect) {
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user