net-predictable/main.go

127 lines
3.1 KiB
Go

package main
import (
"flag"
"fmt"
"github.com/vishvananda/netlink"
"log"
"os"
)
func main() {
var (
err error
mainlog = log.New(os.Stderr, "net-predictable: ", log.Lmsgprefix|log.Ltime)
ifnparam string
force, info bool
main IfNameType
)
flag.StringVar(&ifnparam, "ifname", "", "Interface name to rename")
flag.BoolVar(&force, "force", false, "Force update name of interface")
flag.BoolVar(&info, "info", false, "Show interface details")
flag.IntVar((*int)(&main), "main", int(IfNameLoc), fmt.Sprintf("Main interface name to use: %v",
map[string]IfNameType{
"Kernel": IfNameKern,
"MAC": IfNameMAC,
"Location": IfNameLoc,
},
))
flag.Parse()
// Probe different methods to get interface name
var ifname = ""
for _, v := range []string{
ifnparam,
os.Getenv("INTERFACE"),
os.Getenv("MDEV"),
os.Getenv("IFNAME"),
} {
if v != "" {
ifname = v
break
}
}
if ifname == "" {
mainlog.Println("No interface name provided")
return
}
mainlog.SetPrefix(fmt.Sprintf("net-predictable (%s): ", ifname))
var l netlink.Link
if l, err = netlink.LinkByName(ifname); err != nil {
mainlog.Fatalln("Interface", ifname, "doesn't exist or disappeared before it could be selected")
}
var cif iface
if cif, err = New(ifname); err != nil {
mainlog.Println("Failed creating interface data:", err)
return
}
var should bool
if should, err = cif.shouldRun(); err != nil {
mainlog.Println(err)
}
if !info && (!force && !should) {
mainlog.Println("Interface is already renamed, exiting")
return
}
if err = cif.ProcMAC(); err != nil {
mainlog.Println("Failed to process interface MAC path:", err)
}
if err = cif.ProcLoc(); err != nil {
mainlog.Println("Failed to process interface HW Location path:", err)
}
// Just print information
if info {
mainlog.Println("Selected Interface:", ifname)
mainlog.Println("HW Location Name:", cif.names[IfNameLoc])
mainlog.Println("MAC Name:", cif.names[IfNameMAC])
return
}
// Main name
// This must be set before the next are following as altname cannot be added if a interface with the same name exists
if ifname == cif.names[main] {
mainlog.Println("Interface already named correctly, skipping")
} else if cif.names[main] != "" {
mainlog.Printf("Renaming %s to %s\n", ifname, cif.names[main])
if err = netlink.LinkSetName(l, cif.names[main]); err != nil {
mainlog.Fatalf("Could not rename interface %s: %s\n", ifname, err)
}
} else {
mainlog.Println("Main interface naming method is unavailable for this interface, skipping")
}
// Alt names
var result = make(map[string]int)
for k, v := range cif.names {
if k != main {
result[v]++
}
}
// Invalidate main name
result[cif.names[main]]--
// Invalidate already present alternative names
for _, v := range l.Attrs().AltNames {
result[v]--
}
for k, v := range result {
if v != 1 {
continue
}
mainlog.Printf("Adding altname %s for %s\n", k, ifname)
if err = netlink.LinkAddAltName(l, k); err != nil {
mainlog.Printf("Adding altname %s failed for %s: %s\n", k, ifname, err)
}
}
}