The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/6851
This e-mail was sent by the LXC bot, direct replies will not reach the author unless they happen to be subscribed to this list. === Description (from pull-request) ===
From 23af6d64dafeff7c3c0e1899b9a7fc9c5f7802b1 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Fri, 7 Feb 2020 10:50:05 +0000 Subject: [PATCH 1/2] lxd/device/nic/bridged: Switches to dnsmasq.DHCPAllocatedIPs() Removes local duplicated function that did the same thing. Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/device/nic_bridged.go | 109 ++------------------------------------ 1 file changed, 3 insertions(+), 106 deletions(-) diff --git a/lxd/device/nic_bridged.go b/lxd/device/nic_bridged.go index ad089ae747..06a6a9eabf 100644 --- a/lxd/device/nic_bridged.go +++ b/lxd/device/nic_bridged.go @@ -6,7 +6,6 @@ import ( "encoding/binary" "encoding/hex" "fmt" - "io/ioutil" "math/big" "math/rand" "net" @@ -683,7 +682,7 @@ func (d *nicBridged) allocateFilterIPs(n *network.Network) (net.IP, net.IP, erro // If we need to generate either a new IPv4 or IPv6, load existing IPs used in network. if (IPv4 == nil && canIPv4Allocate) || (IPv6 == nil && canIPv6Allocate) { // Get existing allocations in network. - IPv4Allocs, IPv6Allocs, err := d.getDHCPAllocatedIPs(d.config["parent"]) + IPv4Allocs, IPv6Allocs, err := dnsmasq.DHCPAllocatedIPs(d.config["parent"]) if err != nil { return nil, nil, err } @@ -752,112 +751,10 @@ func (d *nicBridged) networkDHCPValidIP(subnet *net.IPNet, ranges []network.DHCP return false } -// getDHCPAllocatedIPs returns a map of IPs currently allocated (statically and dynamically) -// in dnsmasq for a specific network. The returned map is keyed by a 16 byte array representing -// the net.IP format. The value of each map item is a dhcpAllocation struct containing at least -// whether the allocation was static or dynamic and optionally instance name or MAC address. -// MAC addresses are only included for dynamic IPv4 allocations (where name is not reliable). -// Static allocations are not overridden by dynamic allocations, allowing for instance name to be -// included for static IPv6 allocations. IPv6 addresses that are dynamically assigned cannot be -// reliably linked to instances using either name or MAC because dnsmasq does not record the MAC -// address for these records, and the recorded host name can be set by the instance if the dns.mode -// for the network is set to "dynamic" and so cannot be trusted, so in this case we do not return -// any identifying info. -func (d *nicBridged) getDHCPAllocatedIPs(network string) (map[[4]byte]dhcpAllocation, map[[16]byte]dhcpAllocation, error) { - IPv4s := make(map[[4]byte]dhcpAllocation) - IPv6s := make(map[[16]byte]dhcpAllocation) - - // First read all statically allocated IPs. - files, err := ioutil.ReadDir(shared.VarPath("networks", network, "dnsmasq.hosts")) - if err != nil { - return IPv4s, IPv6s, err - } - - for _, entry := range files { - IPv4, IPv6, err := d.getDHCPStaticIPs(network, entry.Name()) - if err != nil { - return IPv4s, IPv6s, err - } - - if IPv4.IP != nil { - var IPKey [4]byte - copy(IPKey[:], IPv4.IP.To4()) - IPv4s[IPKey] = IPv4 - } - - if IPv6.IP != nil { - var IPKey [16]byte - copy(IPKey[:], IPv6.IP.To16()) - IPv6s[IPKey] = IPv6 - } - } - - // Next read all dynamic allocated IPs. - file, err := os.Open(shared.VarPath("networks", network, "dnsmasq.leases")) - if err != nil { - return IPv4s, IPv6s, err - } - defer file.Close() - - scanner := bufio.NewScanner(file) - for scanner.Scan() { - fields := strings.Fields(scanner.Text()) - if len(fields) == 5 { - IP := net.ParseIP(fields[2]) - if IP == nil { - return IPv4s, IPv6s, fmt.Errorf("Error parsing IP address: %v", fields[2]) - } - - // Handle IPv6 addresses. - if IP.To4() == nil { - var IPKey [16]byte - copy(IPKey[:], IP.To16()) - - // Don't replace IPs from static config as more reliable. - if IPv6s[IPKey].Name != "" { - continue - } - - IPv6s[IPKey] = dhcpAllocation{ - Static: false, - IP: IP.To16(), - } - } else { - // MAC only available in IPv4 leases. - MAC, err := net.ParseMAC(fields[1]) - if err != nil { - return IPv4s, IPv6s, err - } - - var IPKey [4]byte - copy(IPKey[:], IP.To4()) - - // Don't replace IPs from static config as more reliable. - if IPv4s[IPKey].Name != "" { - continue - } - - IPv4s[IPKey] = dhcpAllocation{ - MAC: MAC, - Static: false, - IP: IP.To4(), - } - } - } - } - - err = scanner.Err() - if err != nil { - return IPv4s, IPv6s, err - } - - return IPv4s, IPv6s, nil -} - // getDHCPFreeIPv4 attempts to find a free IPv4 address for the device. // It first checks whether there is an existing allocation for the instance. // If no previous allocation, then a free IP is picked from the ranges configured. -func (d *nicBridged) getDHCPFreeIPv4(usedIPs map[[4]byte]dhcpAllocation, n *network.Network, ctName string, deviceMAC string) (net.IP, error) { +func (d *nicBridged) getDHCPFreeIPv4(usedIPs map[[4]byte]dnsmasq.DHCPAllocation, n *network.Network, ctName string, deviceMAC string) (net.IP, error) { MAC, err := net.ParseMAC(deviceMAC) if err != nil { return nil, err @@ -931,7 +828,7 @@ func (d *nicBridged) getDHCPFreeIPv4(usedIPs map[[4]byte]dhcpAllocation, n *netw // DHCPv6 stateful mode is enabled without custom ranges, then an EUI64 IP is generated from the // device's MAC address. Finally if stateful custom ranges are enabled, then a free IP is picked // from the ranges configured. -func (d *nicBridged) getDHCPFreeIPv6(usedIPs map[[16]byte]dhcpAllocation, n *network.Network, ctName string, deviceMAC string) (net.IP, error) { +func (d *nicBridged) getDHCPFreeIPv6(usedIPs map[[16]byte]dnsmasq.DHCPAllocation, n *network.Network, ctName string, deviceMAC string) (net.IP, error) { netConfig := n.Config() lxdIP, subnet, err := net.ParseCIDR(netConfig["ipv6.address"]) if err != nil { From 8b5b235daf30e8540f79a16dea1f760ac88fe097 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Fri, 7 Feb 2020 10:53:20 +0000 Subject: [PATCH 2/2] lxd/device/nic/bridged: Switches to dnsmasq.DHCPStaticIPs() Removes local duplicated function. Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/device/nic_bridged.go | 47 +++------------------------------------ 1 file changed, 3 insertions(+), 44 deletions(-) diff --git a/lxd/device/nic_bridged.go b/lxd/device/nic_bridged.go index 06a6a9eabf..7c81eb04d7 100644 --- a/lxd/device/nic_bridged.go +++ b/lxd/device/nic_bridged.go @@ -482,9 +482,9 @@ func (d *nicBridged) removeFilters(m deviceConfig.Device) error { } // Read current static IP allocation configured from dnsmasq host config (if exists). - var IPv4, IPv6 dhcpAllocation + var IPv4, IPv6 dnsmasq.DHCPAllocation if shared.PathExists(shared.VarPath("networks", m["parent"], "dnsmasq.hosts") + "/" + d.inst.Name()) { - IPv4, IPv6, err = d.getDHCPStaticIPs(m["parent"], d.inst.Name()) + IPv4, IPv6, err = dnsmasq.DHCPStaticIPs(m["parent"], d.inst.Name()) if err != nil { return fmt.Errorf("Failed to retrieve static IPs for filter removal from %s: %v", m["name"], err) } @@ -493,47 +493,6 @@ func (d *nicBridged) removeFilters(m deviceConfig.Device) error { return d.state.Firewall.InstanceNicBridgedRemoveFilters(m, IPv4.IP, IPv6.IP) } -// getDHCPStaticIPs retrieves the dnsmasq statically allocated IPs for a instance. -// Returns IPv4 and IPv6 dhcpAllocation structs respectively. -func (d *nicBridged) getDHCPStaticIPs(network string, instanceName string) (dhcpAllocation, dhcpAllocation, error) { - var IPv4, IPv6 dhcpAllocation - - file, err := os.Open(shared.VarPath("networks", network, "dnsmasq.hosts") + "/" + instanceName) - if err != nil { - return IPv4, IPv6, err - } - defer file.Close() - - scanner := bufio.NewScanner(file) - for scanner.Scan() { - fields := strings.SplitN(scanner.Text(), ",", -1) - for _, field := range fields { - // Check if field is IPv4 or IPv6 address. - if strings.Count(field, ".") == 3 { - IP := net.ParseIP(field) - if IP.To4() == nil { - return IPv4, IPv6, fmt.Errorf("Error parsing IP address: %v", field) - } - IPv4 = dhcpAllocation{Name: d.inst.Name(), Static: true, IP: IP.To4()} - - } else if strings.HasPrefix(field, "[") && strings.HasSuffix(field, "]") { - IP := net.ParseIP(field[1 : len(field)-1]) - if IP == nil { - return IPv4, IPv6, fmt.Errorf("Error parsing IP address: %v", field) - } - IPv6 = dhcpAllocation{Name: d.inst.Name(), Static: true, IP: IP} - } - } - } - - err = scanner.Err() - if err != nil { - return IPv4, IPv6, err - } - - return IPv4, IPv6, nil -} - // setFilters sets up any network level filters defined for the instance. // These are controlled by the security.mac_filtering, security.ipv4_Filtering and security.ipv6_filtering config keys. func (d *nicBridged) setFilters() (err error) { @@ -644,7 +603,7 @@ func (d *nicBridged) allocateFilterIPs(n *network.Network) (net.IP, net.IP, erro defer dnsmasq.ConfigMutex.Unlock() // Read current static IP allocation configured from dnsmasq host config (if exists). - curIPv4, curIPv6, err := d.getDHCPStaticIPs(d.config["parent"], d.inst.Name()) + curIPv4, curIPv6, err := dnsmasq.DHCPStaticIPs(d.config["parent"], d.inst.Name()) if err != nil && !os.IsNotExist(err) { return nil, nil, err }
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel