in netlink/ip_linux.go [143:212]
func (Netlink) GetIPRoute(filter *Route) ([]*Route, error) {
s, err := getSocket()
if err != nil {
return nil, err
}
req := newRequest(unix.RTM_GETROUTE, unix.NLM_F_DUMP)
ifInfo := newIfInfoMsg()
ifInfo.Family = uint8(filter.Family)
req.addPayload(ifInfo)
msgs, err := s.sendAndWaitForResponse(req)
if err != nil {
return nil, err
}
var routes []*Route
// For each route in the list...
for _, msg := range msgs {
route, err := deserializeRoute(msg)
if err != nil {
return nil, err
}
// Ignore cloned routes.
if route.Flags&unix.RTM_F_CLONED != 0 {
continue
}
// Filter by table.
if (filter.Table == 0 && route.Table != unix.RT_TABLE_MAIN) ||
(filter.Table != 0 && filter.Table != route.Table) {
continue
}
// Filter by protocol.
if filter.Protocol != 0 && filter.Protocol != route.Protocol {
continue
}
// Filter by destination prefix.
if filter.Dst != nil {
fMaskOnes, fMaskBits := filter.Dst.Mask.Size()
if route.Dst == nil {
if fMaskOnes != 0 {
continue
}
} else {
rMaskOnes, rMaskBits := route.Dst.Mask.Size()
if !filter.Dst.IP.Equal(route.Dst.IP) ||
fMaskOnes != rMaskOnes || fMaskBits != rMaskBits {
continue
}
}
}
// Filter by link index.
if filter.LinkIndex != 0 && filter.LinkIndex != route.LinkIndex {
continue
}
routes = append(routes, route)
}
return routes, nil
}