mirror of
https://github.com/rancher/os.git
synced 2025-06-30 00:31:49 +00:00
add ipv4ll auto conf
This commit is contained in:
parent
e3fd8367c0
commit
1dba86a97e
75
cmd/network/ipv4ll.go
Normal file
75
cmd/network/ipv4ll.go
Normal file
@ -0,0 +1,75 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
|
||||
"github.com/j-keck/arping"
|
||||
"github.com/vishvananda/netlink"
|
||||
)
|
||||
|
||||
func AssignLinkLocalIP(link netlink.Link) error {
|
||||
ifaceName := link.Attrs().Name
|
||||
iface, err := net.InterfaceByName(ifaceName)
|
||||
if err != nil {
|
||||
log.Error("could not get information about interface")
|
||||
return err
|
||||
}
|
||||
addrs, err := iface.Addrs()
|
||||
if err != nil {
|
||||
log.Error("Error fetching existing ip on interface")
|
||||
}
|
||||
for _, addr := range addrs {
|
||||
if addr.String()[:7] == "169.254" {
|
||||
log.Info("Link Local IP already set on interface")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
randSource, err := getPseudoRandomGenerator(link.Attrs().HardwareAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// try a random address upto 10 times
|
||||
for i := 0; i < 10; i++ {
|
||||
randGenerator := rand.New(*randSource)
|
||||
randomNum := randGenerator.Uint32()
|
||||
dstIP := getNewIPV4LLAddr(randomNum)
|
||||
if dstIP[2] == 0 || dstIP[2] == 255 {
|
||||
i--
|
||||
continue
|
||||
}
|
||||
_, _, err := arping.PingOverIfaceByName(dstIP, ifaceName)
|
||||
if err != nil {
|
||||
// this ip is not being used
|
||||
addr, err := netlink.ParseAddr(dstIP.String() + "/16")
|
||||
if err != nil {
|
||||
log.Errorf("error while parsing ipv4ll addr, err = %v", err)
|
||||
return err
|
||||
}
|
||||
if err := netlink.AddrAdd(link, addr); err != nil {
|
||||
log.Error("ipv4ll addr add failed")
|
||||
return err
|
||||
}
|
||||
log.Infof("Set %s on %s", dstIP.String(), link.Attrs().Name)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
log.Error("Could not find a suitable ipv4ll")
|
||||
return fmt.Errorf("Could not find a suitable ipv4ll")
|
||||
}
|
||||
|
||||
func getNewIPV4LLAddr(randomNum uint32) net.IP {
|
||||
byte1 := randomNum & 255 // use least significant 8 bits
|
||||
byte2 := randomNum >> 24 // use most significant 8 bits
|
||||
return []byte{169, 254, byte(byte1), byte(byte2)}
|
||||
}
|
||||
|
||||
func getPseudoRandomGenerator(haAddr []byte) (*rand.Source, error) {
|
||||
seed, _ := binary.Varint(haAddr)
|
||||
src := rand.NewSource(seed)
|
||||
return &src, nil
|
||||
}
|
@ -101,6 +101,11 @@ func applyNetConf(link netlink.Link, netConf config.InterfaceConfig) error {
|
||||
if err := cmd.Run(); err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
} else if netConf.IPV4LL {
|
||||
if err := AssignLinkLocalIP(link); err != nil {
|
||||
log.Error("IPV4LL set failed")
|
||||
return err
|
||||
}
|
||||
} else if netConf.Address == "" {
|
||||
return nil
|
||||
} else {
|
||||
|
@ -75,6 +75,7 @@ type InterfaceConfig struct {
|
||||
Match string `yaml:"match,omitempty"`
|
||||
DHCP bool `yaml:"dhcp,omitempty"`
|
||||
Address string `yaml:"address,omitempty"`
|
||||
IPV4LL bool `yaml:"ipv4ll,omitempty"`
|
||||
Gateway string `yaml:"gateway,omitempty"`
|
||||
MTU int `yaml:"mtu,omitempty"`
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user