func()

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
}