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:
		| @@ -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) | ||||
|   | ||||
| @@ -181,9 +181,11 @@ func TestVLANInterfaceNetwork(t *testing.T) { | ||||
| 		logicalInterface{ | ||||
| 			name: "testname", | ||||
| 			config: configMethodStatic{ | ||||
| 				address: net.IPNet{ | ||||
| 					IP:   []byte{192, 168, 1, 100}, | ||||
| 					Mask: []byte{255, 255, 255, 0}, | ||||
| 				addresses: []net.IPNet{ | ||||
| 					{ | ||||
| 						IP:   []byte{192, 168, 1, 100}, | ||||
| 						Mask: []byte{255, 255, 255, 0}, | ||||
| 					}, | ||||
| 				}, | ||||
| 				nameservers: []net.IP{ | ||||
| 					[]byte{8, 8, 8, 8}, | ||||
|   | ||||
| @@ -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 { | ||||
|   | ||||
| @@ -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{ | ||||
| 		IP:   net.IPv4(192, 168, 1, 100), | ||||
| 		Mask: net.IPv4Mask(255, 255, 255, 0), | ||||
| 	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() | ||||
| 	} | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user