Files
openlan/pkg/libol/nl_linux.go
Daniel Ding 6b041b62ce
Some checks failed
Coverage CI / build (push) Has been cancelled
CodeQL / Analyze (go) (push) Has been cancelled
Ubuntu CI / build (push) Has been cancelled
fea: display protocol for prefix route.
2025-09-05 14:23:01 +08:00

125 lines
2.3 KiB
Go
Executable File

package libol
import (
"fmt"
"net"
"github.com/vishvananda/netlink"
)
func GetLocalByGw(addr string) (net.IP, error) {
local := net.IP{}
routes, err := netlink.RouteList(nil, netlink.FAMILY_V4)
if err != nil {
return nil, err
}
dest := net.ParseIP(addr)
if dest == nil {
Warn("GetLocalByGW: parseIP %s failed", addr)
return nil, nil
}
find := netlink.Route{LinkIndex: -1}
for _, rte := range routes {
if rte.Dst != nil && !rte.Dst.Contains(dest) {
continue
}
if find.LinkIndex != -1 && find.Priority < rte.Priority {
continue
}
find = rte
}
if find.LinkIndex != -1 {
index := find.LinkIndex
source := find.Gw
if source == nil {
source = find.Src
}
link, _ := netlink.LinkByIndex(index)
address, _ := netlink.AddrList(link, netlink.FAMILY_V4)
for _, ifAddr := range address {
if ifAddr.Contains(source) {
local = ifAddr.IP
}
}
}
Info("GetLocalByGw: find %s on %s", addr, local)
return local, nil
}
const (
RTPROT_BGP = 0xba
RTPROT_BIRD = 0xc
RTPROT_KERNEL = 0x2
RTPROT_BOOT = 0x3
RTPROT_DHCP = 0x10
RTPROT_ISIS = 0xbb
RTPROT_OSPF = 0xbc
RTPROT_REDIRECT = 0x1
RTPROT_RIP = 0xbd
RTPROT_STATIC = 0x4
RTPROT_UNSPEC = 0x0
RTPROT_ZEBRA = 0xb
)
func RouteProtocol(code int) string {
switch code {
case RTPROT_BGP:
return "bgp"
case RTPROT_KERNEL:
return "kernel"
case RTPROT_BOOT:
return "boot"
case RTPROT_DHCP:
return "dhcp"
case RTPROT_ISIS:
return "isis"
case RTPROT_OSPF:
return "ospf"
case RTPROT_RIP:
return "rip"
case RTPROT_STATIC:
return "static"
default:
return fmt.Sprintf("%d", code)
}
}
func ListRoutes() ([]Prefix, error) {
routes, err := netlink.RouteList(nil, netlink.FAMILY_V4)
if err != nil {
return nil, err
}
var data []Prefix
for _, rte := range routes {
entry := Prefix{
Protocol: RouteProtocol(rte.Protocol),
Priority: rte.Priority,
}
link, err := netlink.LinkByIndex(rte.LinkIndex)
if err == nil {
entry.Link = link.Attrs().Name
}
if rte.Dst == nil {
entry.Dst = "0.0.0.0/0"
} else {
entry.Dst = rte.Dst.String()
}
if len(rte.Gw) == 0 {
entry.Gw = "0.0.0.0"
} else {
entry.Gw = rte.Gw.String()
}
if len(rte.Src) == 0 {
entry.Src = "0.0.0.0"
} else {
entry.Src = rte.Src.String()
}
data = append(data, entry)
}
return data, nil
}