-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support IPv6 addresses during fingerprinting #2536
Changes from 3 commits
8b93d40
94f9542
ad00ec8
f05c3fe
bee4b57
e0d1658
719bdda
536fdde
2073eaf
b0a20b4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,6 @@ | ||
package fingerprint | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"log" | ||
"net" | ||
|
@@ -56,10 +55,11 @@ func NewNetworkFingerprint(logger *log.Logger) Fingerprint { | |
} | ||
|
||
func (f *NetworkFingerprint) Fingerprint(cfg *config.Config, node *structs.Node) (bool, error) { | ||
// newNetwork is populated and addded to the Nodes resources | ||
newNetwork := &structs.NetworkResource{} | ||
var ip string | ||
if node.Resources == nil { | ||
node.Resources = &structs.Resources{} | ||
} | ||
|
||
// Find the named interface | ||
intf, err := f.findInterface(cfg.NetworkInterface) | ||
switch { | ||
case err != nil: | ||
|
@@ -69,66 +69,80 @@ func (f *NetworkFingerprint) Fingerprint(cfg *config.Config, node *structs.Node) | |
return false, nil | ||
} | ||
|
||
if ip, err = f.ipAddress(intf); err != nil { | ||
return false, fmt.Errorf("Unable to find IP address of interface: %s, err: %v", intf.Name, err) | ||
} | ||
|
||
newNetwork.Device = intf.Name | ||
node.Attributes["unique.network.ip-address"] = ip | ||
newNetwork.IP = ip | ||
newNetwork.CIDR = newNetwork.IP + "/32" | ||
|
||
f.logger.Printf("[DEBUG] fingerprint.network: Detected interface %v with IP %v during fingerprinting", intf.Name, ip) | ||
|
||
// Record the throughput of the interface | ||
var mbits int | ||
throughput := f.linkSpeed(intf.Name) | ||
if cfg.NetworkSpeed != 0 { | ||
newNetwork.MBits = cfg.NetworkSpeed | ||
f.logger.Printf("[DEBUG] fingerprint.network: setting link speed to user configured speed: %d", newNetwork.MBits) | ||
mbits = cfg.NetworkSpeed | ||
f.logger.Printf("[DEBUG] fingerprint.network: setting link speed to user configured speed: %d", mbits) | ||
} else if throughput != 0 { | ||
newNetwork.MBits = throughput | ||
f.logger.Printf("[DEBUG] fingerprint.network: link speed for %v set to %v", intf.Name, newNetwork.MBits) | ||
mbits = throughput | ||
f.logger.Printf("[DEBUG] fingerprint.network: link speed for %v set to %v", intf.Name, mbits) | ||
} else { | ||
newNetwork.MBits = defaultNetworkSpeed | ||
mbits = defaultNetworkSpeed | ||
f.logger.Printf("[DEBUG] fingerprint.network: link speed could not be detected and no speed specified by user. Defaulting to %d", defaultNetworkSpeed) | ||
} | ||
|
||
if node.Resources == nil { | ||
node.Resources = &structs.Resources{} | ||
// Create the network resources from the interface | ||
nwResources, err := f.createNetworkResources(mbits, intf) | ||
if err != nil { | ||
return false, err | ||
} | ||
|
||
node.Resources.Networks = append(node.Resources.Networks, newNetwork) | ||
// Add the network resources to the node | ||
for _, nwResource := range nwResources { | ||
node.Resources.Networks = append(node.Resources.Networks, nwResource) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
f.logger.Printf("[DEBUG] fingerprint.network: Detected interface %v with IP: %v, CIDR: %v during fingerprinting", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove during fingerprinting. The prefix is |
||
intf.Name, nwResource.IP, nwResource.CIDR) | ||
} | ||
|
||
if len(nwResources) > 0 { | ||
node.Attributes["unique.network.ip-address"] = nwResources[0].IP | ||
} | ||
|
||
// return true, because we have a network connection | ||
return true, nil | ||
} | ||
|
||
// Gets the ipv4 addr for a network interface | ||
func (f *NetworkFingerprint) ipAddress(intf *net.Interface) (string, error) { | ||
var addrs []net.Addr | ||
var err error | ||
|
||
if addrs, err = f.interfaceDetector.Addrs(intf); err != nil { | ||
return "", err | ||
} | ||
|
||
if len(addrs) == 0 { | ||
return "", errors.New(fmt.Sprintf("Interface %s has no IP address", intf.Name)) | ||
// createNetworkResources creates network resources for every IP | ||
func (f *NetworkFingerprint) createNetworkResources(throughput int, intf *net.Interface) ([]*structs.NetworkResource, error) { | ||
// Find the interface with the name | ||
addrs, err := f.interfaceDetector.Addrs(intf) | ||
if err != nil { | ||
return nil, err | ||
} | ||
nwResources := make([]*structs.NetworkResource, 0) | ||
for _, addr := range addrs { | ||
// Create a new network resource | ||
newNetwork := &structs.NetworkResource{ | ||
Device: intf.Name, | ||
MBits: throughput, | ||
} | ||
|
||
// Find the IP Addr and the CIDR from the Address | ||
var ip net.IP | ||
switch v := (addr).(type) { | ||
case *net.IPNet: | ||
ip = v.IP | ||
newNetwork.IP = v.IP.String() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doesn't this get overrides right below? |
||
case *net.IPAddr: | ||
ip = v.IP | ||
} | ||
|
||
// If the ip is link-local then we ignore it | ||
if ip.IsLinkLocalUnicast() || ip.IsLinkLocalMulticast() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we get a test around these and IPv4/6 CIDRs |
||
continue | ||
} | ||
newNetwork.IP = ip.String() | ||
if ip.To4() != nil { | ||
return ip.String(), nil | ||
newNetwork.CIDR = newNetwork.IP + "/32" | ||
} else { | ||
newNetwork.CIDR = newNetwork.IP + "/128" | ||
} | ||
} | ||
|
||
return "", fmt.Errorf("Couldn't parse IP address for interface %s", intf.Name) | ||
|
||
nwResources = append(nwResources, newNetwork) | ||
} | ||
return nwResources, nil | ||
} | ||
|
||
// Checks if the device is marked UP by the operator | ||
|
@@ -138,8 +152,8 @@ func (f *NetworkFingerprint) isDeviceEnabled(intf *net.Interface) bool { | |
|
||
// Checks if the device has any IP address configured | ||
func (f *NetworkFingerprint) deviceHasIpAddress(intf *net.Interface) bool { | ||
_, err := f.ipAddress(intf) | ||
return err == nil | ||
addrs, err := f.interfaceDetector.Addrs(intf) | ||
return err == nil && len(addrs) != 0 | ||
} | ||
|
||
func (n *NetworkFingerprint) isDeviceLoopBackOrPointToPoint(intf *net.Interface) bool { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to set device name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dadgar Look at https://github.com/hashicorp/nomad/pull/2536/files#diff-e2a9235d588163b6bfb8e29d322e7e84R117 where we are initializing the
structs.NetworkResource