|
@@ -471,9 +471,16 @@ func NetworkLinkAdd(name string, linkType string) error {
|
|
return s.HandleAck(wb.Seq)
|
|
return s.HandleAck(wb.Seq)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// A Route is a subnet associated with the interface to reach it.
|
|
|
|
+type Route struct {
|
|
|
|
+ *net.IPNet
|
|
|
|
+ Iface *net.Interface
|
|
|
|
+ Default bool
|
|
|
|
+}
|
|
|
|
+
|
|
// Returns an array of IPNet for all the currently routed subnets on ipv4
|
|
// Returns an array of IPNet for all the currently routed subnets on ipv4
|
|
// This is similar to the first column of "ip route" output
|
|
// This is similar to the first column of "ip route" output
|
|
-func NetworkGetRoutes() ([]*net.IPNet, error) {
|
|
|
|
|
|
+func NetworkGetRoutes() ([]Route, error) {
|
|
native := nativeEndian()
|
|
native := nativeEndian()
|
|
|
|
|
|
s, err := getNetlinkSocket()
|
|
s, err := getNetlinkSocket()
|
|
@@ -496,7 +503,7 @@ func NetworkGetRoutes() ([]*net.IPNet, error) {
|
|
return nil, err
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
|
|
- res := make([]*net.IPNet, 0)
|
|
|
|
|
|
+ res := make([]Route, 0)
|
|
|
|
|
|
done:
|
|
done:
|
|
for {
|
|
for {
|
|
@@ -525,8 +532,7 @@ done:
|
|
continue
|
|
continue
|
|
}
|
|
}
|
|
|
|
|
|
- var iface *net.Interface = nil
|
|
|
|
- var ipNet *net.IPNet = nil
|
|
|
|
|
|
+ var r Route
|
|
|
|
|
|
msg := (*RtMsg)(unsafe.Pointer(&m.Data[0:syscall.SizeofRtMsg][0]))
|
|
msg := (*RtMsg)(unsafe.Pointer(&m.Data[0:syscall.SizeofRtMsg][0]))
|
|
|
|
|
|
@@ -546,8 +552,8 @@ done:
|
|
}
|
|
}
|
|
|
|
|
|
if msg.Dst_len == 0 {
|
|
if msg.Dst_len == 0 {
|
|
- // Ignore default routes
|
|
|
|
- continue
|
|
|
|
|
|
+ // Default routes
|
|
|
|
+ r.Default = true
|
|
}
|
|
}
|
|
|
|
|
|
attrs, err := syscall.ParseNetlinkRouteAttr(&m)
|
|
attrs, err := syscall.ParseNetlinkRouteAttr(&m)
|
|
@@ -558,18 +564,17 @@ done:
|
|
switch attr.Attr.Type {
|
|
switch attr.Attr.Type {
|
|
case syscall.RTA_DST:
|
|
case syscall.RTA_DST:
|
|
ip := attr.Value
|
|
ip := attr.Value
|
|
- ipNet = &net.IPNet{
|
|
|
|
|
|
+ r.IPNet = &net.IPNet{
|
|
IP: ip,
|
|
IP: ip,
|
|
Mask: net.CIDRMask(int(msg.Dst_len), 8*len(ip)),
|
|
Mask: net.CIDRMask(int(msg.Dst_len), 8*len(ip)),
|
|
}
|
|
}
|
|
case syscall.RTA_OIF:
|
|
case syscall.RTA_OIF:
|
|
index := int(native.Uint32(attr.Value[0:4]))
|
|
index := int(native.Uint32(attr.Value[0:4]))
|
|
- iface, _ = net.InterfaceByIndex(index)
|
|
|
|
- _ = iface
|
|
|
|
|
|
+ r.Iface, _ = net.InterfaceByIndex(index)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- if ipNet != nil {
|
|
|
|
- res = append(res, ipNet)
|
|
|
|
|
|
+ if r.Default || r.IPNet != nil {
|
|
|
|
+ res = append(res, r)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|