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:
Alex Crawford 2014-08-18 12:26:27 -07:00
parent 604ef7ecb4
commit 4a2e417781
4 changed files with 28 additions and 14 deletions

View File

@ -2,6 +2,7 @@ package network
import (
"fmt"
"net"
"sort"
"strconv"
"strings"
@ -25,13 +26,21 @@ type networkInterface interface {
type logicalInterface struct {
name string
hwaddr net.HardwareAddr
config configMethod
children []networkInterface
configDepth int
}
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 {
switch iface := child.(type) {
@ -47,8 +56,8 @@ func (i *logicalInterface) Network() string {
for _, nameserver := range conf.nameservers {
config += fmt.Sprintf("DNS=%s\n", nameserver)
}
if conf.address.IP != nil {
config += fmt.Sprintf("\n[Address]\nAddress=%s\n", conf.address.String())
for _, addr := range conf.addresses {
config += fmt.Sprintf("\n[Address]\nAddress=%s\n", addr.String())
}
for _, route := range conf.routes {
config += fmt.Sprintf("\n[Route]\nDestination=%s\nGateway=%s\n", route.destination.String(), route.gateway)

View File

@ -181,10 +181,12 @@ func TestVLANInterfaceNetwork(t *testing.T) {
logicalInterface{
name: "testname",
config: configMethodStatic{
address: net.IPNet{
addresses: []net.IPNet{
{
IP: []byte{192, 168, 1, 100},
Mask: []byte{255, 255, 255, 0},
},
},
nameservers: []net.IP{
[]byte{8, 8, 8, 8},
},

View File

@ -37,7 +37,7 @@ type route struct {
type configMethod interface{}
type configMethodStatic struct {
address net.IPNet
addresses []net.IPNet
nameservers []net.IP
routes []route
hwaddress net.HardwareAddr
@ -193,20 +193,21 @@ func parseInterfaceStanza(attributes []string, options []string) (*stanzaInterfa
switch confMethod {
case "static":
config := configMethodStatic{
addresses: make([]net.IPNet, 1),
routes: make([]route, 0),
nameservers: make([]net.IP, 0),
}
if addresses, ok := optionMap["address"]; ok {
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 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)
}
if gateways, ok := optionMap["gateway"]; ok {

View File

@ -194,9 +194,11 @@ func TestParseVLANStanzas(t *testing.T) {
func TestParseInterfaceStanzaStaticAddress(t *testing.T) {
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),
},
}
iface, err := parseInterfaceStanza([]string{"eth", "inet", "static"}, options)
@ -207,7 +209,7 @@ func TestParseInterfaceStanzaStaticAddress(t *testing.T) {
if !ok {
t.FailNow()
}
if !reflect.DeepEqual(static.address, expect) {
if !reflect.DeepEqual(static.addresses, expect) {
t.FailNow()
}
}