-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Merged
Merged
Changes from 8 commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
8b93d40
Making the fingerprinter support ipv6 ips
diptanu 94f9542
Finding the appropriate cidr block
diptanu ad00ec8
Ignoring link local addresses
diptanu f05c3fe
Merge branch 'master' into f-ipv6-fingerprint
dadgar bee4b57
Removed redundant code
diptanu e0d1658
Fix api.NetworkResource fields
dadgar 719bdda
Merge branch 'f-ipv6-fingerprint' of github.com:hashicorp/nomad into …
dadgar 536fdde
Added a test
diptanu 2073eaf
Added docs
diptanu b0a20b4
Fixed typo
diptanu File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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,79 @@ 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 | ||
node.Resources.Networks = nwResources | ||
for _, nwResource := range nwResources { | ||
f.logger.Printf("[DEBUG] fingerprint.network: Detected interface %v with IP: %v", intf.Name, nwResource.IP) | ||
} | ||
|
||
// Deprectaed, setting the first IP as unique IP for the node | ||
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. Deprectaed -> Deprecated |
||
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 | ||
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 +151,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 { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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